From a7fa34411e2e578b995f6b7ad2691bea80dcefeb Mon Sep 17 00:00:00 2001 From: abarua-ce Date: Fri, 12 Apr 2024 12:40:13 -0500 Subject: [PATCH 1/7] Added FCT Richards directory --- richards_fct/richards/Richards.h | 3305 ++++++++++++++++ richards_fct/richards/Richards.py | 1873 +++++++++ richards_fct/richards/Richards_new.h | 2966 +++++++++++++++ richards_fct/richards/Richards_new.py | 1745 +++++++++ richards_fct/richards/__init__.py | 6 + richards_fct/richards/cRichards.cpp | 36 + richards_fct/richards/edit/Richards.h.save | 2967 +++++++++++++++ richards_fct/richards/edit/Richards.h.save.1 | 2970 +++++++++++++++ .../richards/edit/Richards.h:Zone.Identifier | 3 + .../richards/edit/Richards.py:Zone.Identifier | 3 + richards_fct/richards/edit/Richards_abc.h | 2967 +++++++++++++++ richards_fct/richards/edit/Richards_abc.py | 1745 +++++++++ .../richards/edit/Richards_corrupted.h | 3205 ++++++++++++++++ .../richards/edit/Richards_corrupted.py | 1848 +++++++++ richards_fct/richards/edit/Richards_edit.h | 3205 ++++++++++++++++ richards_fct/richards/edit/Richards_edit_n.h | 3342 +++++++++++++++++ richards_fct/richards/edit/Richards_edit_n.py | 1873 +++++++++ richards_fct/richards/edit/Richards_fct.h | 3174 ++++++++++++++++ richards_fct/richards/edit/Richards_n.py | 1840 +++++++++ richards_fct/richards/edit/__init__.py | 6 + richards_fct/richards/edit/cRichards.cpp | 36 + richards_fct/richards/new_update/Richards.h | 2966 +++++++++++++++ richards_fct/richards/new_update/Richards.py | 1745 +++++++++ 23 files changed, 43826 insertions(+) create mode 100644 richards_fct/richards/Richards.h create mode 100644 richards_fct/richards/Richards.py create mode 100644 richards_fct/richards/Richards_new.h create mode 100644 richards_fct/richards/Richards_new.py create mode 100644 richards_fct/richards/__init__.py create mode 100644 richards_fct/richards/cRichards.cpp create mode 100755 richards_fct/richards/edit/Richards.h.save create mode 100755 richards_fct/richards/edit/Richards.h.save.1 create mode 100644 richards_fct/richards/edit/Richards.h:Zone.Identifier create mode 100644 richards_fct/richards/edit/Richards.py:Zone.Identifier create mode 100644 richards_fct/richards/edit/Richards_abc.h create mode 100644 richards_fct/richards/edit/Richards_abc.py create mode 100644 richards_fct/richards/edit/Richards_corrupted.h create mode 100644 richards_fct/richards/edit/Richards_corrupted.py create mode 100755 richards_fct/richards/edit/Richards_edit.h create mode 100644 richards_fct/richards/edit/Richards_edit_n.h create mode 100644 richards_fct/richards/edit/Richards_edit_n.py create mode 100644 richards_fct/richards/edit/Richards_fct.h create mode 100755 richards_fct/richards/edit/Richards_n.py create mode 100755 richards_fct/richards/edit/__init__.py create mode 100755 richards_fct/richards/edit/cRichards.cpp create mode 100644 richards_fct/richards/new_update/Richards.h create mode 100644 richards_fct/richards/new_update/Richards.py diff --git a/richards_fct/richards/Richards.h b/richards_fct/richards/Richards.h new file mode 100644 index 0000000000..b1f54a2251 --- /dev/null +++ b/richards_fct/richards/Richards.h @@ -0,0 +1,3305 @@ +#ifndef Richards_H +#define Richards_H +#include +#include +#include +#include "CompKernel.h" +#include "ModelFactory.h" +#include "../mprans/ArgumentsDict.h" +#include "xtensor-python/pyarray.hpp" +#define nnz nSpace + +namespace py = pybind11; +#define POWER_SMOOTHNESS_INDICATOR 2 +#define IS_BETAij_ONE 0 +#define GLOBAL_FCT 0 +namespace proteus +{ + // Power entropy // + inline double ENTROPY(const double& phi, const double& phiL, const double& phiR){ + return 1./2.*std::pow(fabs(phi),2.); + } + inline double DENTROPY(const double& phi, const double& phiL, const double& phiR){ + return fabs(phi)*(phi>=0 ? 1 : -1); + } + // Log entropy // for level set from 0 to 1 + inline double ENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ + return std::log(fabs((phi-phiL)*(phiR-phi))+1E-14); + } + inline double DENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ + return (phiL+phiR-2*phi)*((phi-phiL)*(phiR-phi)>=0 ? 1 : -1)/(fabs((phi-phiL)*(phiR-phi))+1E-14); + } +} + +namespace proteus + +{ + class Richards_base + { + //The base class defining the interface + public: + virtual ~Richards_base(){ + double anb_seepage_flux =1e-16; + } + virtual void calculateResidual(arguments_dict& args)=0; + virtual void calculateJacobian(arguments_dict& args)=0; + virtual void invert(arguments_dict& args)=0; + virtual void FCTStep(arguments_dict& args)=0; + virtual void kth_FCT_step(arguments_dict& args)=0; + virtual void calculateResidual_entropy_viscosity(arguments_dict& args)=0; + virtual void calculateMassMatrix(arguments_dict& args)=0; + }; + + template + class Richards : public Richards_base + { + public: + const int nDOF_test_X_trial_element; + CompKernelType ck; + Richards(): + nDOF_test_X_trial_element(nDOF_test_element*nDOF_trial_element), + ck() + {} + inline + void evaluateCoefficients(const int rowptr[nSpace], + const int colind[nnz], + const double rho, + const double beta, + const double gravity[nSpace], + const double alpha, + const double n_vg, + const double thetaR, + const double thetaSR, + const double KWs[nnz], + const double& u, + double& m, + double& dm, + double f[nSpace], + double df[nSpace], + double a[nnz], + double da[nnz], + double as[nnz], + double& kr, + double& dkr) + { + const int nSpace2 = nSpace * nSpace; + double psiC; + double pcBar; + double pcBar_n; + double pcBar_nM1; + double pcBar_nM2; + double onePlus_pcBar_n; + double sBar; + double sqrt_sBar; + double DsBar_DpsiC; + double thetaW; + double DthetaW_DpsiC; + double vBar; + double vBar2; + double DvBar_DpsiC; + double KWr; + double DKWr_DpsiC; + double rho2 = rho * rho; + double thetaS; + double rhom; + double drhom; + double m_vg; + double pcBarStar; + double sqrt_sBarStar; + + psiC = -u; + m_vg = 1.0 - 1.0 / n_vg; + thetaS = thetaR + thetaSR; + //std::cout<< "Thetas"< 0.0) + { + pcBar = alpha * psiC; + pcBarStar = pcBar; + if (pcBar < 1.0e-8) + pcBarStar = 1.0e-8; + pcBar_nM2 = pow(pcBarStar, n_vg - 2); + pcBar_nM1 = pcBar_nM2 * pcBar; + pcBar_n = pcBar_nM1 * pcBar; + onePlus_pcBar_n = 1.0 + pcBar_n; + + sBar = pow(onePlus_pcBar_n, -m_vg); + /* using -mn = 1-n */ + DsBar_DpsiC = alpha * (1.0 - n_vg) * (sBar/onePlus_pcBar_n)*pcBar_nM1; + + vBar = 1.0-pcBar_nM1*sBar; + vBar2 = vBar*vBar; + DvBar_DpsiC = -alpha*(n_vg-1.0)*pcBar_nM2*sBar - pcBar_nM1*DsBar_DpsiC; + + thetaW = thetaSR*sBar + thetaR; + DthetaW_DpsiC = thetaSR * DsBar_DpsiC; + + sqrt_sBar = sqrt(sBar); + sqrt_sBarStar = sqrt_sBar; + if (sqrt_sBar < 1.0e-8) + sqrt_sBarStar = 1.0e-8; + KWr= sqrt_sBar*vBar2; + DKWr_DpsiC= ((0.5/sqrt_sBarStar)*DsBar_DpsiC*vBar2 + + + 2.0*sqrt_sBar*vBar*DvBar_DpsiC); + } + else + { + thetaW = thetaS; + DthetaW_DpsiC = 0.0; + KWr = 1.0; + DKWr_DpsiC = 0.0; + } + //slight compressibility + rhom = rho*exp(beta*u); + drhom = beta*rhom; + m = rhom*thetaW; + dm = -rhom*DthetaW_DpsiC+drhom*thetaW; + for (int I=0;I thetaS || thetaW <= thetaR) + { + //cek debug + std::cout<<"rho "< 0.0) + { + isDOFBoundary = 1; + bc_u = bc_u_seepage; + } + else + { + isDOFBoundary = 0; + flux = 0.0; + } + } + /* //set DOF flag and flux correctly if seepage face */ + /* if (isSeepageFace) */ + /* { */ + /* if (flux < 0.0 || u < bc_u_seepage) */ + /* { */ + /* isDOFBoundary = 0; */ + /* flux = 0.0; */ + /* } */ + /* else */ + /* { */ + /* isDOFBoundary = 1; */ + /* bc_u = bc_u_seepage; */ + /* } */ + /* } */ + /* //Dirichlet penalty */ + /* if (isDOFBoundary) */ + /* flux += penalty*(u-bc_u); */ + } + else + flux = bc_flux; + } + + void exteriorNumericalFluxJacobian(const int rowptr[nSpace], + const int colind[nnz], + const int isDOFBoundary, + const double n[nSpace], + const double K[nnz], + const double dK[nnz], + const double grad_psi[nSpace], + const double grad_v[nSpace], + const double dK_rho_g[nSpace], + const double v, + const double penalty, + double& fluxJacobian) + { + if (isDOFBoundary) + { + fluxJacobian = 0.0; + for(int I=0;I& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + double sc_uref = args.scalar("sc_uref"); + double sc_alpha = args.scalar("sc_alpha"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& u_dof_old = args.array("u_dof_old"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m = args.array("q_m"); + xt::pyarray& q_u = args.array("q_u"); + xt::pyarray& q_dV = args.array("q_dV"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + int offset_u = args.scalar("offset_u"); + int stride_u = args.scalar("stride_u"); + xt::pyarray& globalResidual = args.array("globalResidual"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& ebqe_phi = args.array("ebqe_phi"); + double epsFact = args.scalar("epsFact"); + xt::pyarray& ebqe_u = args.array("ebqe_u"); + xt::pyarray& ebqe_flux = args.array("ebqe_flux"); + // PARAMETERS FOR EDGE BASED STABILIZATION + double cE = args.scalar("cE"); + double cK = args.scalar("cK"); + // PARAMETERS FOR LOG BASED ENTROPY FUNCTION + double uL = args.scalar("uL"); + double uR = args.scalar("uR"); + // PARAMETERS FOR EDGE VISCOSITY + int numDOFs = args.scalar("numDOFs"); + int NNZ = args.scalar("NNZ"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); + xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); + xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); + xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); + // C matrices + xt::pyarray& Cx = args.array("Cx"); + xt::pyarray& Cy = args.array("Cy"); + xt::pyarray& Cz = args.array("Cz"); + xt::pyarray& CTx = args.array("CTx"); + xt::pyarray& CTy = args.array("CTy"); + xt::pyarray& CTz = args.array("CTz"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); + int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); + // FOR FCT + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& fluxMatrix = args.array("fluxMatrix"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); + xt::pyarray& min_s_bc = args.array("min_s_bc"); + xt::pyarray& max_s_bc = args.array("max_s_bc"); + // AUX QUANTITIES OF INTEREST + xt::pyarray& quantDOFs = args.array("quantDOFs"); + xt::pyarray& sLow = args.array("sLow"); + xt::pyarray& sn = args.array("sn"); + + assert(a_rowptr.data()[nSpace] == nnz); + assert(a_rowptr.data()[nSpace] == nSpace); + //cek should this be read in? + double Ct_sge = 4.0; + //For flux Calculation + //double anb_seepage_flux=0.0; + //anb_seepage_flux = args["anb_seepage_flux"]; + //double anb_seepage_flux = args.scalar("anb_seepage_flux"); + //anb_seepage_flux=0.0; + + xt::pyarray& anb_seepage_flux_n = args.array("anb_seepage_flux_n"); + + + //double anb_seepage_flux=0.0; + double & anb_seepage_flux (args.scalar("anb_seepage_flux")) ; + //double anb_seepage_flux = args.scalar("anb_seepage_flux_n"); + + //double anb_seepage_flux=0.0; + anb_seepage_flux=0.0; + + //loop over elements to compute volume integrals and load them into element and global residual + // + //eN is the element index + //eN_k is the quadrature point index for a scalar + //eN_k_nSpace is the quadrature point index for a vector + //eN_i is the element test function index + //eN_j is the element trial function index + //eN_k_j is the quadrature point index for a trial function + //eN_k_i is the quadrature point index for a trial function + for(int eN=0;eN0) + { + std::cout<<"The seepage flux is "<& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); + xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); + xt::pyarray& globalJacobian = args.array("globalJacobian"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + assert(a_rowptr.data()[nSpace] == nnz); + assert(a_rowptr.data()[nSpace] == nSpace); + double Ct_sge = 4.0; + + + // + //loop over elements to compute volume integrals and load them into the element Jacobians and global Jacobian + // + for(int eN=0;eN& bc_mask = args.array("bc_mask"); + int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern + int numDOFs = args.scalar("numDOFs"); //number of DOFs + double dt = args.scalar("dt"); + xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) + xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn + xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn + xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& limited_solution = args.array("limited_solution"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets + xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices + xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 + xt::pyarray& max_s_bc = args.array("max_s_bc"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int MONOLITHIC = args.scalar("MONOLITHIC"); + register double Rpos[numDOFs], Rneg[numDOFs]; + register double FluxCorrectionMatrix[NNZ]; + register double solL[numDOFs]; + register double sdot[numDOFs]; + ////////////////// + // LOOP in DOFs // + ////////////////// + int ij=0; + for (int i=0; i 0) ? 1. : 0.); + Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); + + //update ij + ij+=1; + //std::cout<<"sdoti error"<0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])) + * FluxCorrectionMatrix[ij]; + alpha_dot = fmin(1.0, beta_ij*fabs(alpha_fA)/MassMatrix.data()[ij]/fmax(1.0e-8,fabs(sdoti-sdotj))); + if (MONOLITHIC == 0) + { + ith_Limiter_times_FluxCorrectionMatrix += alpha_fA; + } + else + { + ith_Limiter_times_FluxCorrectionMatrix += alpha_fA + (LUMPED_MASS_MATRIX == 1 ? 0. : 1.)*dt*alpha_dot*MassMatrix.data()[ij]*(sdoti-sdotj); + } + //update ij + ij+=1; + } + limited_solution.data()[i] = solL[i] + 1./lumped_mass_matrix.data()[i]*ith_Limiter_times_FluxCorrectionMatrix*bc_mask[i]; + } + } + + void kth_FCT_step(arguments_dict& args) + { + int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern + int numDOFs = args.scalar("numDOFs"); //number of DOFs + int num_fct_iter = args.scalar("num_fct_iter"); + double dt = args.scalar("dt"); + xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) + xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn + xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn + xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& solLim = args.array("limited_solution"); + xt::pyarray& MC = args.array("MC"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& FluxMatrix = args.array("FluxMatrix"); + xt::pyarray& limitedFlux = args.array("limited_Flux"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets + xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices + xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 + xt::pyarray& max_s_bc = args.array("max_s_bc"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int MONOLITHIC = args.scalar("MONOLITHIC"); + register double Rpos[numDOFs], Rneg[numDOFs]; + int ij=0; + + ////////////////////////////////////////////////////// + // ********** COMPUTE LOW ORDER SOLUTION ********** // + ////////////////////////////////////////////////////// + if (num_fct_iter == 0) + { // No FCT for global bounds + for (int i=0; i 0) ? 1. : 0.); + // update ij + ij+=1; + } + // compute Q vectors + double mi = ML.data()[i]; + double solLimi = solLim.data()[i]; + double Qposi = mi*(maxi-solLimi); + // compute R vectors + Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + } + ij=0; + for (int i=0; i0 ? Rposi : Rpos[j]); + // compute limited flux + ith_Limiter_times_FluxCorrectionMatrix += Lij*Fluxij; + + // update limited flux + limitedFlux.data()[ij] = Lij*Fluxij; + + //update FluxMatrix + FluxMatrix.data()[ij] = Fluxij; + + //update ij + ij+=1; + } + //update limited solution + double mi = ML.data()[i]; + solLim.data()[i] += 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; + } + } + } + + // ***************************************** // + // ********** HIGH ORDER SOLUTION ********** // + // ***************************************** // + ij=0; + for (int i=0; i 0 ? 1. : 0.); + Pnegi += fij * (fij < 0 ? 1. : 0.); + //update ij + ij+=1; + } + // compute Q vectors // + double mi = ML.data()[i]; + double Qposi = mi*(maxi-solLim.data()[i]); + double Qnegi = mi*(mini-solLim.data()[i]); + // compute R vectors // + Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); + } + + // COMPUTE LIMITERS // + ij=0; + for (int i=0; i 0 ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j]); + // compute ith_limited_flux_correction + ith_limited_flux_correction += Lij*fij; + ij+=1; + } + double mi = ML.data()[i]; + solLim[i] += 1./mi*ith_limited_flux_correction; + } + } + + void calculateResidual_entropy_viscosity(arguments_dict& args) + { + xt::pyarray& globalJacobian = args.array("globalJacobian"); + double Theta = args.scalar("Theta"); + xt::pyarray& bc_mask = args.array("bc_mask"); + double dt = args.scalar("dt"); + xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + double sc_uref = args.scalar("sc_uref"); + double sc_alpha = args.scalar("sc_alpha"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& r_l2g = args.array("r_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + int degree_polynomial = args.scalar("degree_polynomial"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& u_dof_old = args.array("u_dof_old"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m = args.array("q_m"); + xt::pyarray& q_u = args.array("q_u"); + xt::pyarray& q_dV = args.array("q_dV"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + int offset_u = args.scalar("offset_u"); + int stride_u = args.scalar("stride_u"); + xt::pyarray& globalResidual = args.array("globalResidual"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& ebqe_phi = args.array("ebqe_phi"); + double epsFact = args.scalar("epsFact"); + xt::pyarray& ebqe_u = args.array("ebqe_u"); + xt::pyarray& ebqe_flux = args.array("ebqe_flux"); + // PARAMETERS FOR EDGE BASED STABILIZATION + double cE = args.scalar("cE"); + double cK = args.scalar("cK"); + // PARAMETERS FOR LOG BASED ENTROPY FUNCTION + double uL = args.scalar("uL"); + double uR = args.scalar("uR"); + // PARAMETERS FOR EDGE VISCOSITY + int numDOFs = args.scalar("numDOFs"); + int NNZ = args.scalar("NNZ"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); + xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); + xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); + xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); + // C matrices + xt::pyarray& Cx = args.array("Cx"); + xt::pyarray& Cy = args.array("Cy"); + xt::pyarray& Cz = args.array("Cz"); + xt::pyarray& CTx = args.array("CTx"); + xt::pyarray& CTy = args.array("CTy"); + xt::pyarray& CTz = args.array("CTz"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); + int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); + // FOR FCT + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& fluxMatrix = args.array("fluxMatrix"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); + xt::pyarray& min_s_bc = args.array("min_s_bc"); + xt::pyarray& max_s_bc = args.array("max_s_bc"); + // AUX QUANTITIES OF INTEREST + xt::pyarray& quantDOFs = args.array("quantDOFs"); + xt::pyarray& sLow = args.array("sLow"); + xt::pyarray& sn = args.array("sn"); + + xt::pyarray& anb_seepage_flux_n = args.array("anb_seepage_flux_n"); + + + //double anb_seepage_flux=0.0; + double & anb_seepage_flux (args.scalar("anb_seepage_flux")) ; + //double anb_seepage_flux = args.scalar("anb_seepage_flux_n"); + + //double anb_seepage_flux=0.0; + anb_seepage_flux=0.0; + + + register double Rpos[numDOFs], Rneg[numDOFs]; + //register double FluxCorrectionMatrix[NNZ]; + // NOTE: This function follows a different (but equivalent) implementation of the smoothness based indicator than NCLS.h + // Allocate space for the transport matrices + // This is used for first order KUZMIN'S METHOD + register double TransportMatrix[NNZ],TransportMatrixConsistent[NNZ]; + register double TransportMatrixn[NNZ],TransportMatrixConsistentn[NNZ]; + std::valarray u_free_dof(numDOFs); + std::valarray u_free_dof_old(numDOFs); + std::valarray ML2(numDOFs); + + + for(int eN=0;eN0) + { + std::cout<<"The seepage flux is "<("anb_seepage_flux_n"); + //anb_seepage_flux_n=0.0; + + //anb_seepage_flux_n= anb_seepage_flux; + + + + //if (isSeepageFace) + //{ + // anb_seepage_flux+= dS* flux_ext; + // std::cout<<"The seepage flux is "<0){ + // std::cout<<"The seepage flux is "<= 0 && isFluxBoundary_u[ebNE_kb] != 1 ) //outflow. This is handled via the transport matrices. Then flux_ext=0 and dflux_ext!=0 + // { + // dflux_ext = flow; + // flux_ext = 0; + // // save external u + // ebqe_u[ebNE_kb] = u_ext; + // } + //else // inflow. This is handled via the boundary integral. Then flux_ext!=0 and dflux_ext=0 + //{ + //dflux_ext = 0; + // save external u + //ebqe_u[ebNE_kb] = isDOFBoundary_u[ebNE_kb]*ebqe_bc_u_ext[ebNE_kb]+(1-isDOFBoundary_u[ebNE_kb])*u_ext; + //if (isDOFBoundary_u[ebNE_kb] == 1) + // flux_ext = ebqe_bc_u_ext[ebNE_kb]*flow; + //else if (isFluxBoundary_u[ebNE_kb] == 1) + //flux_ext = ebqe_bc_flux_u_ext[ebNE_kb]; + // flux_ext = ebqe_bc_u_ext[ebNE_kb]; + //else + // { + // std::cout<<"warning: VOF open boundary with no external trace, setting to zero for inflow"<= 0.) + { + alpha_numerator_pos += alpha_num; + alpha_denominator_pos += alpha_num; + } + else + { + alpha_numerator_neg += alpha_num; + alpha_denominator_neg += fabs(alpha_num); + } + //update ij + ij+=1; + } + // scale g vector by lumped mass matrix + if (fabs(ML.data()[i] - ML2[i]) > 1.0e-16) + std::cout<<"ML "< 0.0) + // assert( (xi[I] - xj[I]) == delta_x_ij[offset*3+I]); + //gi_times_x += gi[I]*(xi[I]-xj[I]); + gi_times_x += gi[I]*delta_x_ij.data()[offset*3+I]; + } + // compute the positive and negative part of gi*(xi-xj) + SumPos += gi_times_x > 0 ? gi_times_x : 0; + SumNeg += gi_times_x < 0 ? gi_times_x : 0; + } + double sigmaPosi = fmin(1.,(fabs(SumNeg)+1E-15)/(SumPos+1E-15)); + double sigmaNegi = fmin(1.,(SumPos+1E-15)/(fabs(SumNeg)+1E-15)); + double alpha_numi = fabs(sigmaPosi*alpha_numerator_pos + sigmaNegi*alpha_numerator_neg); + double alpha_deni = sigmaPosi*alpha_denominator_pos + sigmaNegi*alpha_denominator_neg; + if (IS_BETAij_ONE == 1) + { + alpha_numi = fabs(alpha_numerator_pos + alpha_numerator_neg); + alpha_deni = alpha_denominator_pos + alpha_denominator_neg; + } + double alphai = alpha_numi/(alpha_deni+1E-15); + quantDOFs.data()[i] = alphai; + + if (POWER_SMOOTHNESS_INDICATOR==0) + psi[i] = 1.0; + else + psi[i] = std::pow(alphai,POWER_SMOOTHNESS_INDICATOR); //NOTE: they use alpha^2 in the paper + } + ///////////////////////////////////////////// + // ** LOOP IN DOFs FOR EDGE BASED TERMS ** // + ///////////////////////////////////////////// + ij=0; + for (int i=0; i Dissipation matrices as well. + double soli = u_free_dof[i]; // solution at time tn for the ith DOF + double solni = u_free_dof_old[i]; // solution at time tn for the ith DOF + for (int I=0;I& bc_mask = args.array("bc_mask"); + //int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern + //int numDOFs = args.scalar("numDOFs"); //number of DOFs + //double dt = args.scalar("dt"); + //xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) + + xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn + //xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn + //xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 + //xt::pyarray& uLow = args.array("uLow"); + //xt::pyarray& uDotLow = args.array("uDotLow"); + //xt::pyarray& limited_solution = args.array("limited_solution"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets + //xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix + //xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices + //xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 + //xt::pyarray& max_s_bc = args.array("max_s_bc"); + //int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + //int MONOLITHIC = args.scalar("MONOLITHIC"); + register double Rpos[numDOFs], Rneg[numDOFs]; + register double FluxCorrectionMatrix[NNZ]; + xt::pyarray& solLim = args.array("limited_solution"); + //register double solL[numDOFs]; + //register double sdot[numDOFs]; + + ij=0; + for (int i=0; i 0 ? 1. : 0.); + Pnegi += fij * (fij < 0 ? 1. : 0.); + //update ij + ij+=1; + } + + // compute Q vectors // + double mi = ML.data()[i]; + double Qposi = mi*(maxi-solLim.data()[i]); + double Qnegi = mi*(mini-solLim.data()[i]); + // compute R vectors // + Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); + } + + ij=0; + for (int i=0; i 0 ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j]); + // compute ith_limited_flux_correction + ith_limited_flux_correction += Lij*fij; + ij+=1; + } + double mi = ML.data()[i]; + solLim[i] += 1./mi*ith_limited_flux_correction; + } + + //std::cout<<"Limiter "<< ith_Limiter_times_FluxCorrectionMatrix < mMax) + { + std::cout<<"mass out of bounds "< 0) ? 1. : 0.); + // Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); + // ij+=1; + // } + // double mi = ML[i]; + // double solni = u_dof_old[i]; + // double Qposi = mi*(maxi-solni); + // double Qnegi = mi*(mini-solni); + + //std::cout << Qposi << std::endl; + // Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + // Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); + + //if (Rpos[i] < 0) + //{ + // std::cout << mi << "\t" << maxi << "\t" << solni << std::endl; + // std::cout << Qposi << "\t" << Pposi << std::endl; + // std::cout << Rpos[i] << std::endl; + //abort(); + //} + //} + + //ij=0; + //for (int i=0; i 1.0 || Rposi < 0.0) + //std::cout << "Rposi: " << Rposi << std::endl; + //if (Rnegi > 1.0 || Rnegi < 0.0) + //std::cout << "Rnegi: " << Rnegi << std::endl; + + // LOOP OVER THE SPARSITY PATTERN (j-LOOP)// + // for (int offset=csrRowIndeces_DofLoops.data()[i]; + // offset0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])); + // //Lij=0.0; + // ith_Limiter_times_FluxCorrectionMatrix += Lij*FluxCorrectionMatrix[ij]; + // //update ij + // ij+=1; + // } + // double mi = ML[i]; + // double solni = u_dof_old[i]; + // globalResidual[i] = solni + 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; + //} + } + + + void invert(arguments_dict& args) + { + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + xt::pyarray& globalResidual = args.array("globalResidual"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + int numDOFs = args.scalar("numDOFs"); + for (int i=0; i mMax) + { + std::cout<<"mass out of bounds "<("dt"); + xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + //element boundary + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + //physics + int nElements_global = args.scalar("nElements_global"); + //new + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + //end new + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& r_l2g = args.array("r_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + int degree_polynomial = args.scalar("degree_polynomial"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); + xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); + xt::pyarray& globalJacobian = args.array("globalJacobian"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + //std::cout<<"ndjaco address "<(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + else if (nSpaceIn == 2) + return proteus::chooseAndAllocateDiscretization2D(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + else + { + assert(nSpaceIn == 3); + return proteus::chooseAndAllocateDiscretization(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + } + } +};//proteus +#endif \ No newline at end of file diff --git a/richards_fct/richards/Richards.py b/richards_fct/richards/Richards.py new file mode 100644 index 0000000000..b299d490ce --- /dev/null +++ b/richards_fct/richards/Richards.py @@ -0,0 +1,1873 @@ +from __future__ import division +from builtins import range +from past.utils import old_div +import proteus +from .cRichards import * +import numpy as np +from proteus.Transport import OneLevelTransport +from proteus.Transport import TC_base, NonlinearEquation, logEvent, memory +from proteus.Transport import FluxBoundaryConditions, Comm, cfemIntegrals +from proteus.Transport import DOFBoundaryConditions, Quadrature +from proteus.mprans import cArgumentsDict +from proteus.LinearAlgebraTools import SparseMat +from proteus import TimeIntegration +from proteus.NonlinearSolvers import ExplicitLumpedMassMatrixForRichards +from proteus.NonlinearSolvers import Newton + + +class ThetaScheme(TimeIntegration.BackwardEuler): + def __init__(self,transport,integrateInterpolationPoints=False): + self.transport=transport + TimeIntegration.BackwardEuler.__init__(self,transport, integrateInterpolationPoints) + def updateTimeHistory(self,resetFromDOF=False): + TimeIntegration.BackwardEuler.updateTimeHistory(self,resetFromDOF) + self.transport.u_dof_old[:] = self.u +class RKEV(TimeIntegration.SSP): + from proteus import TimeIntegration + """ + Wrapper for SSPRK time integration using EV + + ... more to come ... + """ + + def __init__(self, transport, timeOrder=1, runCFL=0.1, integrateInterpolationPoints=False): + TimeIntegration.SSP.__init__(self, transport, integrateInterpolationPoints=integrateInterpolationPoints) + self.runCFL = runCFL + self.dtLast = None + self.isAdaptive = True + # About the cfl + assert transport.coefficients.STABILIZATION_TYPE > 0, "SSP method just works for edge based EV methods; i.e., STABILIZATION_TYPE>0" + assert hasattr(transport, 'edge_based_cfl'), "No edge based cfl defined" + self.cfl = transport.edge_based_cfl + # Stuff particular for SSP + self.timeOrder = timeOrder # order of approximation + self.nStages = timeOrder # number of stages total + self.lstage = 0 # last stage completed + # storage vectors + self.u_dof_last = {} + # per component stage values, list with array at each stage + self.u_dof_stage = {} + for ci in range(self.nc): + if ('m', ci) in transport.q: + self.u_dof_last[ci] = transport.u[ci].dof.copy() + self.u_dof_stage[ci] = [] + for k in range(self.nStages + 1): + self.u_dof_stage[ci].append(transport.u[ci].dof.copy()) + #print() + + + # def set_dt(self, DTSET): + # self.dt = DTSET # don't update t + def choose_dt(self): + comm = Comm.get() + maxCFL = 1.0e-6 + maxCFL = max(maxCFL, comm.globalMax(self.cfl.max())) + self.dt = old_div(self.runCFL, maxCFL) + if self.dtLast is None: + self.dtLast = self.dt + self.t = self.tLast + self.dt + self.substeps = [self.t for i in range(self.nStages)] # Manuel is ignoring different time step levels for now + #print("Hi, This is Arnob") + + + def initialize_dt(self, t0, tOut, q): + """ + Modify self.dt + """ + self.tLast = t0 + self.choose_dt() + self.t = t0 + self.dt + + def setCoefficients(self): + """ + beta are all 1's here + mwf not used right now + """ + self.alpha = np.zeros((self.nStages, self.nStages), 'd') + self.dcoefs = np.zeros((self.nStages), 'd') + + def updateStage(self): + """ + Need to switch to use coefficients + """ + self.lstage += 1 + assert self.timeOrder in [1, 2, 3] + assert self.lstage > 0 and self.lstage <= self.timeOrder + if self.timeOrder == 3: + if self.lstage == 1: + logEvent("First stage of SSP33 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + # update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] + elif self.lstage == 2: + logEvent("Second stage of SSP33 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + self.u_dof_stage[ci][self.lstage] *= old_div(1., 4.) + self.u_dof_stage[ci][self.lstage] += 3. / 4. * self.u_dof_last[ci] + # Update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] + elif self.lstage == 3: + logEvent("Third stage of SSP33 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + self.u_dof_stage[ci][self.lstage] *= old_div(2.0, 3.0) + self.u_dof_stage[ci][self.lstage] += 1.0 / 3.0 * self.u_dof_last[ci] + # update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_last[ci] + # update solution to u[0].dof + self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] + elif self.timeOrder == 2: + if self.lstage == 1: + logEvent("First stage of SSP22 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + # Update u_dof_old + self.transport.u_dof_old[:] = self.transport.u[ci].dof + elif self.lstage == 2: + logEvent("Second stage of SSP22 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + self.u_dof_stage[ci][self.lstage][:] *= old_div(1., 2.) + self.u_dof_stage[ci][self.lstage][:] += 1. / 2. * self.u_dof_last[ci] + # update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_last[ci] + # update solution to u[0].dof + self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] + else: + assert self.timeOrder == 1 + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof[:] + self.transport.u_dof_old[:] = self.transport.u[ci].dof + #self.print("Hi, Arnob") + + def initializeTimeHistory(self, resetFromDOF=True): + """ + Push necessary information into time history arrays + """ + for ci in range(self.nc): + self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] + for k in range(self.nStages): + self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] + + def updateTimeHistory(self, resetFromDOF=False): + """ + assumes successful step has been taken + """ + + self.t = self.tLast + self.dt + for ci in range(self.nc): + self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] + for k in range(self.nStages): + self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] + self.lstage = 0 + self.dtLast = self.dt + self.tLast = self.t + + def generateSubsteps(self, tList): + """ + create list of substeps over time values given in tList. These correspond to stages + """ + self.substeps = [] + tLast = self.tLast + for t in tList: + dttmp = t - tLast + self.substeps.extend([tLast + dttmp for i in range(self.nStages)]) + tLast = t + + def resetOrder(self, order): + """ + initialize data structures for stage updges + """ + self.timeOrder = order # order of approximation + self.nStages = order # number of stages total + self.lstage = 0 # last stage completed + # storage vectors + # per component stage values, list with array at each stage + self.u_dof_stage = {} + for ci in range(self.nc): + if ('m', ci) in self.transport.q: + self.u_dof_stage[ci] = [] + for k in range(self.nStages + 1): + self.u_dof_stage[ci].append(self.transport.u[ci].dof.copy()) + self.substeps = [self.t for i in range(self.nStages)] + + def setFromOptions(self, nOptions): + """ + allow classes to set various numerical parameters + """ + if 'runCFL' in dir(nOptions): + self.runCFL = nOptions.runCFL + flags = ['timeOrder'] + for flag in flags: + if flag in dir(nOptions): + val = getattr(nOptions, flag) + setattr(self, flag, val) + if flag == 'timeOrder': + self.resetOrder(self.timeOrder) + + + +class Coefficients(proteus.TransportCoefficients.TC_base): + """ + version of Re where element material type id's used in evals + """ + from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2 + from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchten_sd_het + def __init__(self, + nd, + Ksw_types, + vgm_n_types, + vgm_alpha_types, + thetaR_types, + thetaSR_types, + gravity, + density, + beta, + diagonal_conductivity=True, + getSeepageFace=None, + # FOR EDGE BASED EV + STABILIZATION_TYPE=0, + ENTROPY_TYPE=2, # logarithmic + LUMPED_MASS_MATRIX=False, + MONOLITHIC=True, + FCT=True, + num_fct_iter=1, + # FOR ENTROPY VISCOSITY + cE=1.0, + uL=0.0, + uR=1.0, + # FOR ARTIFICIAL COMPRESSION + cK=1.0, + # OUTPUT quantDOFs + outputQuantDOFs=False, ): + self.anb_seepage_flux= 0.00 + #self.anb_seepage_flux_n =0.0 + variableNames=['pressure_head'] + nc=1 + mass={0:{0:'nonlinear'}} + advection={0:{0:'nonlinear'}} + diffusion={0:{0:{0:'nonlinear'}}} + potential={0:{0:'u'}} + reaction={0:{0:'linear'}} + hamiltonian={} + self.getSeepageFace=getSeepageFace + self.gravity=gravity + self.rho = density + self.beta=beta + self.vgm_n_types = vgm_n_types + self.vgm_alpha_types = vgm_alpha_types + self.thetaR_types = thetaR_types + self.thetaSR_types = thetaSR_types + self.elementMaterialTypes = None + self.exteriorElementBoundaryTypes = None + self.materialTypes_q = None + self.materialTypes_ebq = None + self.materialTypes_ebqe = None + self.nd = nd + self.nMaterialTypes = len(thetaR_types) + self.q = {}; self.ebqe = {}; self.ebq = {}; self.ebq_global={} + #try to allow some flexibility in input of permeability/conductivity tensor + self.diagonal_conductivity = diagonal_conductivity + self.Ksw_types_in = Ksw_types + if self.diagonal_conductivity: + sparseDiffusionTensors = {(0,0):(np.arange(self.nd+1,dtype='i'), + np.arange(self.nd,dtype='i'))} + + assert len(Ksw_types.shape) in [1,2], "if diagonal conductivity true then Ksw_types scalar or vector of diagonal entries" + #allow scalar input Ks + if len(Ksw_types.shape)==1: + self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd),'d') + for I in range(self.nd): + self.Ksw_types[:,I] = Ksw_types + else: + self.Ksw_types = Ksw_types + else: #full + sparseDiffusionTensors = {(0,0):(np.arange(self.nd**2+1,step=self.nd,dtype='i'), + np.array([list(range(self.nd)) for row in range(self.nd)],dtype='i'))} + assert len(Ksw_types.shape) in [1,2], "if full tensor conductivity true then Ksw_types scalar or 'flattened' row-major representation of entries" + if len(Ksw_types.shape)==1: + self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd**2),'d') + for I in range(self.nd): + self.Ksw_types[:,I*self.nd+I] = Ksw_types + else: + assert Ksw_types.shape[1] == self.nd**2 + self.Ksw_types = Ksw_types + # EDGE BASED (AND ENTROPY) VISCOSITY + self.LUMPED_MASS_MATRIX = LUMPED_MASS_MATRIX + self.MONOLITHIC = MONOLITHIC + self.STABILIZATION_TYPE = STABILIZATION_TYPE + self.ENTROPY_TYPE = ENTROPY_TYPE + self.FCT = FCT + self.num_fct_iter=num_fct_iter + self.uL = uL + self.uR = uR + self.cK = cK + self.forceStrongConditions = True + self.cE = cE + self.outputQuantDOFs = outputQuantDOFs + TC_base.__init__(self, + nc, + mass, + advection, + diffusion, + potential, + reaction, + hamiltonian, + variableNames, + sparseDiffusionTensors = sparseDiffusionTensors, + useSparseDiffusion = True) + + def initializeMesh(self,mesh): + from proteus.SubsurfaceTransportCoefficients import BlockHeterogeneousCoefficients + self.elementMaterialTypes,self.exteriorElementBoundaryTypes,self.elementBoundaryTypes = BlockHeterogeneousCoefficients(mesh).initializeMaterialTypes() + #want element boundary material types for evaluating heterogeneity + #not boundary conditions + self.isSeepageFace = np.zeros((mesh.nExteriorElementBoundaries_global),'i') + if self.getSeepageFace != None: + for ebNE in range(mesh.nExteriorElementBoundaries_global): + #mwf missing ebNE-->ebN? + ebN = mesh.exteriorElementBoundariesArray[ebNE] + #print "eb flag",mesh.elementBoundaryMaterialTypes[ebN] + #print("Hi, Arnob") + #print self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) + self.isSeepageFace[ebNE] = self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) + #print (self.isSeepageFace) + def initializeElementQuadrature(self,t,cq): + self.materialTypes_q = self.elementMaterialTypes + self.q_shape = cq[('u',0)].shape + #self.anb_seepage_flux= anb_seepage_flux + #print("The seepage is ", anb_seepage_flux) +# cq['Ks'] = np.zeros(self.q_shape,'d') +# for k in range(self.q_shape[1]): +# cq['Ks'][:,k] = self.Ksw_types[self.elementMaterialTypes,0] + self.q[('vol_frac',0)] = np.zeros(self.q_shape,'d') + def initializeElementBoundaryQuadrature(self,t,cebq,cebq_global): + self.materialTypes_ebq = np.zeros(cebq[('u',0)].shape[0:2],'i') + self.ebq_shape = cebq[('u',0)].shape + for ebN_local in range(self.ebq_shape[1]): + self.materialTypes_ebq[:,ebN_local] = self.elementMaterialTypes + self.ebq[('vol_frac',0)] = np.zeros(self.ebq_shape,'d') + + def initializeGlobalExteriorElementBoundaryQuadrature(self,t,cebqe): + self.materialTypes_ebqe = self.exteriorElementBoundaryTypes + self.ebqe_shape = cebqe[('u',0)].shape + self.ebqe[('vol_frac',0)] = np.zeros(self.ebqe_shape,'d') + # + + + def evaluate(self,t,c): + if c[('u',0)].shape == self.q_shape: + materialTypes = self.materialTypes_q + vol_frac = self.q[('vol_frac',0)] + elif c[('u',0)].shape == self.ebqe_shape: + materialTypes = self.materialTypes_ebqe + vol_frac = self.ebqe[('vol_frac',0)] + elif c[('u',0)].shape == self.ebq_shape: + materialTypes = self.materialTypes_ebq + vol_frac = self.ebq[('vol_frac',0)] + else: + assert False, "no materialType found to match c[('u',0)].shape= %s " % c[('u',0)].shape + self.conservativeHeadRichardsMualemVanGenuchten_sd_het(self.sdInfo[(0,0)][0], + self.sdInfo[(0,0)][1], + materialTypes, + self.rho, + self.beta, + self.gravity, + self.vgm_alpha_types, + self.vgm_n_types, + self.thetaR_types, + self.thetaSR_types, + self.Ksw_types, + c[('u',0)], + c[('m',0)], + c[('dm',0,0)], + c[('f',0)], + c[('df',0,0)], + c[('a',0,0)], + c[('da',0,0,0)], + vol_frac) + # print "Picard---------------------------------------------------------------" + # c[('df',0,0)][:] = 0.0 + # c[('da',0,0,0)][:] = 0.0 +# self.conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2(materialTypes, +# self.rho, +# self.beta, +# self.gravity, +# self.vgm_alpha_types, +# self.vgm_n_types, +# self.thetaR_types, +# self.thetaSR_types, +# self.Ksw_types, +# c[('u',0)], +# c[('m',0)], +# c[('dm',0,0)], +# c[('f',0)], +# c[('df',0,0)], +# c[('a',0,0)], +# c[('da',0,0,0)]) + #mwf debug + if (np.isnan(c[('da',0,0,0)]).any() or + np.isnan(c[('a',0,0)]).any() or + np.isnan(c[('df',0,0)]).any() or + np.isnan(c[('f',0)]).any() or + np.isnan(c[('u',0)]).any() or + np.isnan(c[('m',0)]).any() or + np.isnan(c[('dm',0,0)]).any()): + import pdb + pdb.set_trace() + + def postStep(self, t, firstStep=False): + # #anb_seepage_flux_n[:]= self.anb_seepage_flux + with open('seepage_stab_0', "a") as f: + # f.write("\n Time"+ ",\t" +"Seepage\n") + f.write(repr(t)+ ",\t")# +repr(np.sum(self.LevelModel.anb_seepage_flux_n))) + +class LevelModel(proteus.Transport.OneLevelTransport): + nCalls=0 + def __init__(self, + uDict, + phiDict, + testSpaceDict, + matType, + dofBoundaryConditionsDict, + dofBoundaryConditionsSetterDict, + coefficients, + elementQuadrature, + elementBoundaryQuadrature, + fluxBoundaryConditionsDict=None, + advectiveFluxBoundaryConditionsSetterDict=None, + diffusiveFluxBoundaryConditionsSetterDictDict=None, + stressTraceBoundaryConditionsSetterDict=None, + stabilization=None, + shockCapturing=None, + conservativeFluxDict=None, + numericalFluxType=None, + TimeIntegrationClass=None, + massLumping=False, + reactionLumping=False, + options=None, + name='defaultName', + reuse_trial_and_test_quadrature=True, + sd = True, + movingDomain=False, + bdyNullSpace=False): + self.bdyNullSpace=bdyNullSpace + # + #set the objects describing the method and boundary conditions + # + self.movingDomain=movingDomain + self.tLast_mesh=None + # + self.name=name + self.sd=sd + self.Hess=False + self.lowmem=True + self.timeTerm=True#allow turning off the time derivative + #self.lowmem=False + self.testIsTrial=True + self.phiTrialIsTrial=True + self.u = uDict + self.ua = {}#analytical solutions + self.phi = phiDict + self.dphi={} + self.matType = matType + #mwf try to reuse test and trial information across components if spaces are the same + self.reuse_test_trial_quadrature = reuse_trial_and_test_quadrature#True#False + if self.reuse_test_trial_quadrature: + for ci in range(1,coefficients.nc): + assert self.u[ci].femSpace.__class__.__name__ == self.u[0].femSpace.__class__.__name__, "to reuse_test_trial_quad all femSpaces must be the same!" + self.u_dof_old = None + ## Simplicial Mesh + self.mesh = self.u[0].femSpace.mesh #assume the same mesh for all components for now + self.testSpace = testSpaceDict + self.dirichletConditions = dofBoundaryConditionsDict + self.dirichletNodeSetList=None #explicit Dirichlet conditions for now, no Dirichlet BC constraints + self.coefficients = coefficients + self.coefficients.initializeMesh(self.mesh) + self.nc = self.coefficients.nc + self.stabilization = stabilization + self.shockCapturing = shockCapturing + self.conservativeFlux = conservativeFluxDict #no velocity post-processing for now + self.fluxBoundaryConditions=fluxBoundaryConditionsDict + self.advectiveFluxBoundaryConditionsSetterDict=advectiveFluxBoundaryConditionsSetterDict + self.diffusiveFluxBoundaryConditionsSetterDictDict = diffusiveFluxBoundaryConditionsSetterDictDict + #determine whether the stabilization term is nonlinear + self.stabilizationIsNonlinear = False + #cek come back + if self.stabilization != None: + for ci in range(self.nc): + if ci in coefficients.mass: + for flag in list(coefficients.mass[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.advection: + for flag in list(coefficients.advection[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.diffusion: + for diffusionDict in list(coefficients.diffusion[ci].values()): + for flag in list(diffusionDict.values()): + if flag != 'constant': + self.stabilizationIsNonlinear=True + if ci in coefficients.potential: + for flag in list(coefficients.potential[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.reaction: + for flag in list(coefficients.reaction[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.hamiltonian: + for flag in list(coefficients.hamiltonian[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + #determine if we need element boundary storage + self.elementBoundaryIntegrals = {} + for ci in range(self.nc): + self.elementBoundaryIntegrals[ci] = ((self.conservativeFlux != None) or + (numericalFluxType != None) or + (self.fluxBoundaryConditions[ci] == 'outFlow') or + (self.fluxBoundaryConditions[ci] == 'mixedFlow') or + (self.fluxBoundaryConditions[ci] == 'setFlow')) + # + #calculate some dimensions + # + self.nSpace_global = self.u[0].femSpace.nSpace_global #assume same space dim for all variables + self.nDOF_trial_element = [u_j.femSpace.max_nDOF_element for u_j in list(self.u.values())] + self.nDOF_phi_trial_element = [phi_k.femSpace.max_nDOF_element for phi_k in list(self.phi.values())] + self.n_phi_ip_element = [phi_k.femSpace.referenceFiniteElement.interpolationConditions.nQuadraturePoints for phi_k in list(self.phi.values())] + self.nDOF_test_element = [femSpace.max_nDOF_element for femSpace in list(self.testSpace.values())] + self.nFreeDOF_global = [dc.nFreeDOF_global for dc in list(self.dirichletConditions.values())] + self.nVDOF_element = sum(self.nDOF_trial_element) + self.nFreeVDOF_global = sum(self.nFreeDOF_global) + # + NonlinearEquation.__init__(self,self.nFreeVDOF_global) + # + #build the quadrature point dictionaries from the input (this + #is just for convenience so that the input doesn't have to be + #complete) + # + elementQuadratureDict={} + elemQuadIsDict = isinstance(elementQuadrature,dict) + if elemQuadIsDict: #set terms manually + for I in self.coefficients.elementIntegralKeys: + if I in elementQuadrature: + elementQuadratureDict[I] = elementQuadrature[I] + + else: + elementQuadratureDict[I] = elementQuadrature['default'] + else: + for I in self.coefficients.elementIntegralKeys: + elementQuadratureDict[I] = elementQuadrature + if self.stabilization != None: + for I in self.coefficients.elementIntegralKeys: + if elemQuadIsDict: + if I in elementQuadrature: + elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature[I] + else: + elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature['default'] + else: + elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature + if self.shockCapturing != None: + for ci in self.shockCapturing.components: + if elemQuadIsDict: + if ('numDiff',ci,ci) in elementQuadrature: + elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature[('numDiff',ci,ci)] + #print("Hi, Arnob1") + #print(anb_seepage_flux) + else: + elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature['default'] + #print("Hi, Arnob2") + #print(anb_seepage_flux) + else: + elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature + print("Hi, Arnob3") + #print(anb_seepage_flux) + if massLumping: + for ci in list(self.coefficients.mass.keys()): + elementQuadratureDict[('m',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + print("Hi, Arnob4") + #print(anb_seepage_flux) + for I in self.coefficients.elementIntegralKeys: + elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + print("Hi, Arnob5") + #print(anb_seepage_flux) + if reactionLumping: + for ci in list(self.coefficients.mass.keys()): + elementQuadratureDict[('r',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + print("Hi, Arnob6") + #print(anb_seepage_flux) + for I in self.coefficients.elementIntegralKeys: + elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + print("Hi, Arnob7") + #print(anb_seepage_flux) + elementBoundaryQuadratureDict={} + if isinstance(elementBoundaryQuadrature,dict): #set terms manually + for I in self.coefficients.elementBoundaryIntegralKeys: + if I in elementBoundaryQuadrature: + elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature[I] + print("Hi, Arnob8") + #print(anb_seepage_flux) + else: + elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature['default'] + #print("Hi, Arnob9") + #print(anb_seepage_flux) + else: + for I in self.coefficients.elementBoundaryIntegralKeys: + elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature + print("Hi, Arnob10") + #print(anb_seepage_flux) + # + # find the union of all element quadrature points and + # build a quadrature rule for each integral that has a + # weight at each point in the union + #mwf include tag telling me which indices are which quadrature rule? + (self.elementQuadraturePoints,self.elementQuadratureWeights, + self.elementQuadratureRuleIndeces) = Quadrature.buildUnion(elementQuadratureDict) + self.nQuadraturePoints_element = self.elementQuadraturePoints.shape[0] + self.nQuadraturePoints_global = self.nQuadraturePoints_element*self.mesh.nElements_global + # + #Repeat the same thing for the element boundary quadrature + # + (self.elementBoundaryQuadraturePoints, + self.elementBoundaryQuadratureWeights, + self.elementBoundaryQuadratureRuleIndeces) = Quadrature.buildUnion(elementBoundaryQuadratureDict) + self.nElementBoundaryQuadraturePoints_elementBoundary = self.elementBoundaryQuadraturePoints.shape[0] + self.nElementBoundaryQuadraturePoints_global = (self.mesh.nElements_global* + self.mesh.nElementBoundaries_element* + self.nElementBoundaryQuadraturePoints_elementBoundary) +# if isinstance(self.u[0].femSpace,C0_AffineLinearOnSimplexWithNodalBasis): +# print self.nQuadraturePoints_element +# if self.nSpace_global == 3: +# assert(self.nQuadraturePoints_element == 5) +# elif self.nSpace_global == 2: +# assert(self.nQuadraturePoints_element == 6) +# elif self.nSpace_global == 1: +# assert(self.nQuadraturePoints_element == 3) +# +# print self.nElementBoundaryQuadraturePoints_elementBoundary +# if self.nSpace_global == 3: +# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) +# elif self.nSpace_global == 2: +# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) +# elif self.nSpace_global == 1: +# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 1) + + # + #storage dictionaries + self.scalars_element = set() + # + #simplified allocations for test==trial and also check if space is mixed or not + # + self.q={} + self.ebq={} + self.ebq_global={} + self.ebqe={} + self.phi_ip={} + self.edge_based_cfl = np.zeros(self.u[0].dof.shape)+100 + #mesh + #self.q['x'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,3),'d') + self.q[('dV_u', 0)] = (old_div(1.0, self.mesh.nElements_global)) * np.ones((self.mesh.nElements_global, self.nQuadraturePoints_element), 'd') + self.ebqe['x'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,3),'d') + self.q[('u',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') + self.q[('grad(u)',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') + self.q['velocity'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') + self.q[('m',0)] = self.q[('u',0)].copy() + self.q[('mt',0)] = self.q[('u',0)].copy() + self.q[('m_last',0)] = self.q[('u',0)].copy() + self.q[('m_tmp',0)] = self.q[('u',0)].copy() + self.q[('cfl',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') + self.q[('numDiff',0,0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') + self.ebqe[('u',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.ebqe[('grad(u)',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') + self.ebqe['velocity'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') + self.ebqe[('advectiveFlux_bc_flag',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'i') + self.ebqe[('advectiveFlux_bc',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.ebqe[('advectiveFlux',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.ebqe[('penalty')] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.points_elementBoundaryQuadrature= set() + self.scalars_elementBoundaryQuadrature= set([('u',ci) for ci in range(self.nc)]) + self.vectors_elementBoundaryQuadrature= set() + self.tensors_elementBoundaryQuadrature= set() + self.inflowBoundaryBC = {} + self.inflowBoundaryBC_values = {} + self.inflowFlux = {} + for cj in range(self.nc): + self.inflowBoundaryBC[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,),'i') + self.inflowBoundaryBC_values[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nDOF_trial_element[cj]),'d') + self.inflowFlux[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.internalNodes = set(range(self.mesh.nNodes_global)) + #identify the internal nodes this is ought to be in mesh + ##\todo move this to mesh + for ebNE in range(self.mesh.nExteriorElementBoundaries_global): + ebN = self.mesh.exteriorElementBoundariesArray[ebNE] + eN_global = self.mesh.elementBoundaryElementsArray[ebN,0] + ebN_element = self.mesh.elementBoundaryLocalElementBoundariesArray[ebN,0] + for i in range(self.mesh.nNodes_element): + if i != ebN_element: + I = self.mesh.elementNodesArray[eN_global,i] + self.internalNodes -= set([I]) + self.nNodes_internal = len(self.internalNodes) + self.internalNodesArray=np.zeros((self.nNodes_internal,),'i') + for nI,n in enumerate(self.internalNodes): + self.internalNodesArray[nI]=n + # + del self.internalNodes + self.internalNodes = None + logEvent("Updating local to global mappings",2) + self.updateLocal2Global() + logEvent("Building time integration object",2) + logEvent(memory("inflowBC, internalNodes,updateLocal2Global","OneLevelTransport"),level=4) + #mwf for interpolating subgrid error for gradients etc + if self.stabilization and self.stabilization.usesGradientStabilization: + self.timeIntegration = TimeIntegrationClass(self,integrateInterpolationPoints=True) + else: + self.timeIntegration = TimeIntegrationClass(self) + + if options != None: + self.timeIntegration.setFromOptions(options) + logEvent(memory("TimeIntegration","OneLevelTransport"),level=4) + logEvent("Calculating numerical quadrature formulas",2) + self.calculateQuadrature() + #lay out components/equations contiguously for now + self.offset = [0] + for ci in range(1,self.nc): + self.offset += [self.offset[ci-1]+self.nFreeDOF_global[ci-1]] + self.stride = [1 for ci in range(self.nc)] + #use contiguous layout of components for parallel, requires weak DBC's + # mql. Some ASSERTS to restrict the combination of the methods + if self.coefficients.STABILIZATION_TYPE > 0: + pass + #assert self.timeIntegration.isSSP == True, "If STABILIZATION_TYPE>0, use RKEV timeIntegration within VOF model" + #cond = 'levelNonlinearSolver' in dir(options) and (options.levelNonlinearSolver == + # ExplicitLumpedMassMatrixForRichards or options.levelNonlinearSolver == ExplicitConsistentMassMatrixForRichards) + #assert cond, "If STABILIZATION_TYPE>0, use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards or ExplicitConsistentMassMatrixForRichards" + try: + if 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards: + assert self.coefficients.LUMPED_MASS_MATRIX, "If levelNonlinearSolver=ExplicitLumpedMassMatrix, use LUMPED_MASS_MATRIX=True" + except: + pass + if self.coefficients.LUMPED_MASS_MATRIX == True: + cond = self.coefficients.STABILIZATION_TYPE == 2 + assert cond, "Use lumped mass matrix just with: STABILIZATION_TYPE=2 (smoothness based stab.)" + cond = 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards + assert cond, "Use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards when the mass matrix is lumped" + + ################################################################# + ####################ARNOB_FCT_EDIT############################### + ################################################################# + + if self.coefficients.LUMPED_MASS_MATRIX == False: + cond = self.coefficients.STABILIZATION_TYPE == 2 + assert cond, "Use lumped mass matrix just with: STABILIZATION_TYPE=2 (smoothness based stab.)" + cond = 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == Newton + #assert cond, "Use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards when the mass matrix is lumped" + + + + + + if self.coefficients.FCT == True: + cond = self.coefficients.STABILIZATION_TYPE > 0, "Use FCT just with STABILIZATION_TYPE>0; i.e., edge based stabilization" + # END OF ASSERTS + + # cek adding empty data member for low order numerical viscosity structures here for now + self.ML = None # lumped mass matrix + self.MC_global = None # consistent mass matrix + self.cterm_global = None + self.cterm_transpose_global = None + # dL_global and dC_global are not the full matrices but just the CSR arrays containing the non zero entries + self.residualComputed=False #TMP + self.dLow= None + self.fluxMatrix = None + self.uDotLow = None + self.uLow = None + self.dt_times_dC_minus_dL = None + self.min_s_bc = None + self.max_s_bc = None + # Aux quantity at DOFs to be filled by optimized code (MQL) + self.quantDOFs = np.zeros(self.u[0].dof.shape, 'd') + self.sLow = np.zeros(self.u[0].dof.shape, 'd') + self.sHigh = np.zeros(self.u[0].dof.shape, 'd') + self.sn = np.zeros(self.u[0].dof.shape, 'd') + self.anb_seepage_flux_n = np.zeros(self.u[0].dof.shape, 'd') + comm = Comm.get() + self.comm=comm + if comm.size() > 1: + assert numericalFluxType != None and numericalFluxType.useWeakDirichletConditions,"You must use a numerical flux to apply weak boundary conditions for parallel runs" + self.offset = [0] + for ci in range(1,self.nc): + self.offset += [ci] + self.stride = [self.nc for ci in range(self.nc)] + # + logEvent(memory("stride+offset","OneLevelTransport"),level=4) + + + if numericalFluxType != None: + if options is None or options.periodicDirichletConditions is None: + self.numericalFlux = numericalFluxType(self, + dofBoundaryConditionsSetterDict, + advectiveFluxBoundaryConditionsSetterDict, + diffusiveFluxBoundaryConditionsSetterDictDict) + else: + self.numericalFlux = numericalFluxType(self, + dofBoundaryConditionsSetterDict, + advectiveFluxBoundaryConditionsSetterDict, + diffusiveFluxBoundaryConditionsSetterDictDict, + options.periodicDirichletConditions) + else: + self.numericalFlux = None + #set penalty terms + #cek todo move into numerical flux initialization + if 'penalty' in self.ebq_global: + for ebN in range(self.mesh.nElementBoundaries_global): + for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): + self.ebq_global['penalty'][ebN,k] = old_div(self.numericalFlux.penalty_constant,(self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power)) + #penalty term + #cek move to Numerical flux initialization + if 'penalty' in self.ebqe: + for ebNE in range(self.mesh.nExteriorElementBoundaries_global): + ebN = self.mesh.exteriorElementBoundariesArray[ebNE] + for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): + self.ebqe['penalty'][ebNE,k] = old_div(self.numericalFlux.penalty_constant,self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power) + logEvent(memory("numericalFlux","OneLevelTransport"),level=4) + self.elementEffectiveDiametersArray = self.mesh.elementInnerDiametersArray + #use post processing tools to get conservative fluxes, None by default + from proteus import PostProcessingTools + self.velocityPostProcessor = PostProcessingTools.VelocityPostProcessingChooser(self) + logEvent(memory("velocity postprocessor","OneLevelTransport"),level=4) + #helper for writing out data storage + from proteus import Archiver + self.elementQuadratureDictionaryWriter = Archiver.XdmfWriter() + self.elementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() + self.exteriorElementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() + #TODO get rid of this + for ci,fbcObject in list(self.fluxBoundaryConditionsObjectsDict.items()): + self.ebqe[('advectiveFlux_bc_flag',ci)] = np.zeros(self.ebqe[('advectiveFlux_bc',ci)].shape,'i') + for t,g in list(fbcObject.advectiveFluxBoundaryConditionsDict.items()): + if ci in self.coefficients.advection: + self.ebqe[('advectiveFlux_bc',ci)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) + self.ebqe[('advectiveFlux_bc_flag',ci)][t[0],t[1]] = 1 + + if hasattr(self.numericalFlux,'setDirichletValues'): + self.numericalFlux.setDirichletValues(self.ebqe) + if not hasattr(self.numericalFlux,'isDOFBoundary'): + self.numericalFlux.isDOFBoundary = {0:np.zeros(self.ebqe[('u',0)].shape,'i')} + if not hasattr(self.numericalFlux,'ebqe'): + self.numericalFlux.ebqe = {('u',0):np.zeros(self.ebqe[('u',0)].shape,'d')} + #TODO how to handle redistancing calls for calculateCoefficients,calculateElementResidual etc + self.globalResidualDummy = None + compKernelFlag=0 + self.delta_x_ij=None + self.richards = cRichards_base(self.nSpace_global, + self.nQuadraturePoints_element, + self.u[0].femSpace.elementMaps.localFunctionSpace.dim, + self.u[0].femSpace.referenceFiniteElement.localFunctionSpace.dim, + self.testSpace[0].referenceFiniteElement.localFunctionSpace.dim, + self.nElementBoundaryQuadraturePoints_elementBoundary, + compKernelFlag) + if self.movingDomain: + self.MOVING_DOMAIN=1.0 + else: + self.MOVING_DOMAIN=0.0 + #cek hack + self.movingDomain=False + self.MOVING_DOMAIN=0.0 + if self.mesh.nodeVelocityArray is None: + self.mesh.nodeVelocityArray = np.zeros(self.mesh.nodeArray.shape,'d') + self.forceStrongConditions=True + self.dirichletConditionsForceDOF = {} + if self.forceStrongConditions: + for cj in range(self.nc): + self.dirichletConditionsForceDOF[cj] = DOFBoundaryConditions(self.u[cj].femSpace,dofBoundaryConditionsSetterDict[cj],weakDirichletConditions=False) + def FCTStep(self): + import pdb + rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() + limited_solution = np.zeros((len(rowptr) - 1),'d') + #self.u_free_dof_stage_0_l = np.zeros((len(rowptr) - 1),'d') + #self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage], # soln + #fromFreeToGlobal=0 + #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + # self.offset[0], + # self.stride[0], + # self.dirichletConditions[0].global2freeGlobal_global_dofs, + # self.dirichletConditions[0].global2freeGlobal_free_dofs, + # self.u_free_dof_stage_0_l, + # self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage]) + argsDict = cArgumentsDict.ArgumentsDict() + argsDict["bc_mask"] = self.bc_mask + argsDict["NNZ"] = self.nnz + argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs + argsDict["dt"] = self.timeIntegration.dt + argsDict["lumped_mass_matrix"] = self.ML + argsDict["soln"] = self.sn + argsDict["pn"] = self.u[0].dof + argsDict["solH"] = self.sHigh + argsDict["uLow"] = self.sLow + argsDict["uDotLow"] = self.uDotLow + argsDict["limited_solution"] = limited_solution + argsDict["csrRowIndeces_DofLoops"] = rowptr + argsDict["csrColumnOffsets_DofLoops"] = colind + argsDict["MassMatrix"] = MassMatrix + argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL + argsDict["min_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0]) #cek hack just set from physical bounds + argsDict["max_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0] + self.coefficients.thetaSR_types[0]) #cek hack + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["MONOLITHIC"] =0#cek hack self.coefficients.MONOLITHIC + argsDict["anb_seepage_flux_n"]= self.anb_seepage_flux_n + #pdb.set_trace() + self.richards.FCTStep(argsDict) + + # self.nnz, # number of non zero entries + # len(rowptr) - 1, # number of DOFs + # self.timeIntegration.dt, + # self.ML, # Lumped mass matrix + # self.sn, + # self.u_dof_old, + # self.sHigh, # high order solution + # self.sLow, + # limited_solution, + # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) + # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) + # MassMatrix, + # self.dt_times_dC_minus_dL, + # self.min_s_bc, + # self.max_s_bc, + # self.coefficients.LUMPED_MASS_MATRIX, + # self.coefficients.MONOLITHIC) + old_dof = self.u[0].dof.copy() + self.invert(limited_solution, self.u[0].dof) + self.timeIntegration.u[:] = self.u[0].dof + #fromFreeToGlobal=1 #direction copying + #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + # self.offset[0], + # self.stride[0], + # self.dirichletConditions[0].global2freeGlobal_global_dofs, + # self.dirichletConditions[0].global2freeGlobal_free_dofs, + # self.u[0].dof, + # limited_solution) + def kth_FCT_step(self): + #import pdb + #pdb.set_trace() + rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() + limitedFlux = np.zeros(self.nnz) + limited_solution = np.zeros((len(rowptr) - 1),'d') + #limited_solution[:] = self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage] + fromFreeToGlobal=0 #direction copying + cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + self.offset[0], + self.stride[0], + self.dirichletConditions[0].global2freeGlobal_global_dofs, + self.dirichletConditions[0].global2freeGlobal_free_dofs, + limited_solution, + self.timeintegration.u_dof_stage[0][self.timeIntegration.lstage]) + + self.richards.kth_FCT_step( + self.timeIntegration.dt, + self.coefficients.num_fct_iter, + self.nnz, # number of non zero entries + len(rowptr) - 1, # number of DOFs + MassMatrix, + self.ML, # Lumped mass matrix + self.u_dof_old, + limited_solution, + self.uDotLow, + self.uLow, + self.dLow, + self.fluxMatrix, + limitedFlux, + rowptr, + colind) + + self.timeIntegration.u[:] = limited_solution + #self.u[0].dof[:] = limited_solution + fromFreeToGlobal=1 #direction copying + cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + self.offset[0], + self.stride[0], + self.dirichletConditions[0].global2freeGlobal_global_dofs, + self.dirichletConditions[0].global2freeGlobal_free_dofs, + self.u[0].dof, + limited_solution) + def calculateCoefficients(self): + pass + def calculateElementResidual(self): + if self.globalResidualDummy != None: + self.getResidual(self.u[0].dof,self.globalResidualDummy) + def getResidual(self,u,r): + import pdb + import copy + """ + Calculate the element residuals and add in to the global residual + """ + cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, + self.jacobian) + if self.u_dof_old is None: + # Pass initial condition to u_dof_old + self.u_dof_old = np.copy(self.u[0].dof) + rowptr, colind, nzval = self.jacobian.getCSRrepresentation() + nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix + r.fill(0.0) + ######################## + ### COMPUTE C MATRIX ### + ######################## + if self.cterm_global is None: + # since we only need cterm_global to persist, we can drop the other self.'s + self.cterm = {} + self.cterm_a = {} + self.cterm_global = {} + self.cterm_transpose = {} + self.cterm_a_transpose = {} + self.cterm_global_transpose = {} + rowptr, colind, nzval = self.jacobian.getCSRrepresentation() + nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix + di = self.q[('grad(u)', 0)].copy() # direction of derivative + # JACOBIANS (FOR ELEMENT TRANSFORMATION) + self.q[('J')] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nSpace_global, + self.nSpace_global), + 'd') + self.q[('inverse(J)')] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nSpace_global, + self.nSpace_global), + 'd') + self.q[('det(J)')] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element), + 'd') + self.u[0].femSpace.elementMaps.getJacobianValues(self.elementQuadraturePoints, + self.q['J'], + self.q['inverse(J)'], + self.q['det(J)']) + self.q['abs(det(J))'] = np.abs(self.q['det(J)']) + # SHAPE FUNCTIONS + self.q[('w', 0)] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nDOF_test_element[0]), + 'd') + self.q[('w*dV_m', 0)] = self.q[('w', 0)].copy() + self.u[0].femSpace.getBasisValues(self.elementQuadraturePoints, self.q[('w', 0)]) + cfemIntegrals.calculateWeightedShape(self.elementQuadratureWeights[('u', 0)], + self.q['abs(det(J))'], + self.q[('w', 0)], + self.q[('w*dV_m', 0)]) + # GRADIENT OF TEST FUNCTIONS + self.q[('grad(w)', 0)] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nDOF_test_element[0], + self.nSpace_global), + 'd') + self.u[0].femSpace.getBasisGradientValues(self.elementQuadraturePoints, + self.q['inverse(J)'], + self.q[('grad(w)', 0)]) + self.q[('grad(w)*dV_f', 0)] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nDOF_test_element[0], + self.nSpace_global), + 'd') + cfemIntegrals.calculateWeightedShapeGradients(self.elementQuadratureWeights[('u', 0)], + self.q['abs(det(J))'], + self.q[('grad(w)', 0)], + self.q[('grad(w)*dV_f', 0)]) + ########################## + ### LUMPED MASS MATRIX ### + ########################## + # assume a linear mass term + dm = np.ones(self.q[('u', 0)].shape, 'd') + elementMassMatrix = np.zeros((self.mesh.nElements_global, + self.nDOF_test_element[0], + self.nDOF_trial_element[0]), 'd') + cfemIntegrals.updateMassJacobian_weak_lowmem(dm, + self.q[('w', 0)], + self.q[('w*dV_m', 0)], + elementMassMatrix) + self.MC_a = nzval.copy() + self.MC_global = SparseMat(self.nFreeDOF_global[0], + self.nFreeDOF_global[0], + nnz, + self.MC_a, + colind, + rowptr) + cfemIntegrals.zeroJacobian_CSR(self.nnz, self.MC_global) + cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.csrRowIndeces[(0, 0)], + self.csrColumnOffsets[(0, 0)], + elementMassMatrix, + self.MC_global) + self.ML = np.zeros((self.nFreeDOF_global[0],), 'd') + for i in range(self.nFreeDOF_global[0]): + self.ML[i] = self.MC_a[rowptr[i]:rowptr[i + 1]].sum() + np.testing.assert_almost_equal(self.ML.sum(), + self.mesh.volume, + err_msg="Trace of lumped mass matrix should be the domain volume", verbose=True) + for d in range(self.nSpace_global): # spatial dimensions + # C matrices + self.cterm[d] = np.zeros((self.mesh.nElements_global, + self.nDOF_test_element[0], + self.nDOF_trial_element[0]), 'd') + self.cterm_a[d] = nzval.copy() + #self.cterm_a[d] = np.zeros(nzval.size) + self.cterm_global[d] = SparseMat(self.nFreeDOF_global[0], + self.nFreeDOF_global[0], + nnz, + self.cterm_a[d], + colind, + rowptr) + cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global[d]) + di[:] = 0.0 + di[..., d] = 1.0 + cfemIntegrals.updateHamiltonianJacobian_weak_lowmem(di, + self.q[('grad(w)*dV_f', 0)], + self.q[('w', 0)], + self.cterm[d]) # int[(di*grad(wj))*wi*dV] + cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.csrRowIndeces[(0, 0)], + self.csrColumnOffsets[(0, 0)], + self.cterm[d], + self.cterm_global[d]) + # C Transpose matrices + self.cterm_transpose[d] = np.zeros((self.mesh.nElements_global, + self.nDOF_test_element[0], + self.nDOF_trial_element[0]), 'd') + self.cterm_a_transpose[d] = nzval.copy() + self.cterm_global_transpose[d] = SparseMat(self.nFreeDOF_global[0], + self.nFreeDOF_global[0], + nnz, + self.cterm_a_transpose[d], + colind, + rowptr) + cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global_transpose[d]) + di[:] = 0.0 + di[..., d] = -1.0 + cfemIntegrals.updateAdvectionJacobian_weak_lowmem(di, + self.q[('w', 0)], + self.q[('grad(w)*dV_f', 0)], + self.cterm_transpose[d]) # -int[(-di*grad(wi))*wj*dV] + cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.csrRowIndeces[(0, 0)], + self.csrColumnOffsets[(0, 0)], + self.cterm_transpose[d], + self.cterm_global_transpose[d]) + + rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() + else: + Cy = np.zeros(Cx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() + else: + Cz = np.zeros(Cx.shape, 'd') + rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() + else: + CTy = np.zeros(CTx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() + else: + CTz = np.zeros(CTx.shape, 'd') + + # This is dummy. I just care about the csr structure of the sparse matrix + self.dLow = np.zeros(Cx.shape, 'd') + self.fluxMatrix = np.zeros(Cx.shape, 'd') + self.dt_times_dC_minus_dL = np.zeros(Cx.shape, 'd') + nFree = len(rowptr)-1 + self.min_s_bc = np.zeros(nFree, 'd') + 1E10 + self.max_s_bc = np.zeros(nFree, 'd') - 1E10 + self.uDotLow = np.zeros(nFree, 'd') + self.uLow = np.zeros(nFree, 'd') + # + # cek end computationa of cterm_global + # + # cek showing mquezada an example of using cterm_global sparse matrix + # calculation y = c*x where x==1 + # direction=0 + #rowptr, colind, c = self.cterm_global[direction].getCSRrepresentation() + #y = np.zeros((self.nFreeDOF_global[0],),'d') + #x = np.ones((self.nFreeDOF_global[0],),'d') + # ij=0 + # for i in range(self.nFreeDOF_global[0]): + # for offset in range(rowptr[i],rowptr[i+1]): + # j = colind[offset] + # y[i] += c[ij]*x[j] + # ij+=1 + #Load the unknowns into the finite element dof + self.timeIntegration.calculateCoefs() + self.timeIntegration.calculateU(u) + self.setUnknowns(self.timeIntegration.u) + #cek can put in logic to skip of BC's don't depend on t or u + #Dirichlet boundary conditions + self.numericalFlux.setDirichletValues(self.ebqe) + #flux boundary conditions + #cek hack, just using advective flux for flux BC for now + for t,g in list(self.fluxBoundaryConditionsObjectsDict[0].advectiveFluxBoundaryConditionsDict.items()): + self.ebqe[('advectiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) + self.ebqe[('advectiveFlux_bc_flag',0)][t[0],t[1]] = 1 + # for t,g in self.fluxBoundaryConditionsObjectsDict[0].diffusiveFluxBoundaryConditionsDict.iteritems(): + # self.ebqe[('diffusiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) + # self.ebqe[('diffusiveFlux_bc_flag',0)][t[0],t[1]] = 1 + #self.shockCapturing.lag=True + if self.forceStrongConditions: + self.bc_mask = np.ones_like(self.u[0].dof) + for cj in range(len(self.dirichletConditionsForceDOF)): + for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): + self.u[cj].dof[dofN] = g(self.dirichletConditionsForceDOF[cj].DOFBoundaryPointDict[dofN],self.timeIntegration.t) + self.u_dof_old[dofN] = self.u[cj].dof[dofN] + self.bc_mask[dofN] = 0.0 + degree_polynomial = 1 + try: + degree_polynomial = self.u[0].femSpace.order + except: + pass + + argsDict = cArgumentsDict.ArgumentsDict() + argsDict["bc_mask"] = self.bc_mask + argsDict["dt"] = self.timeIntegration.dt + argsDict["Theta"] = 1.0 + argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi + argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi + argsDict["mesh_dof"] = self.mesh.nodeArray + argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray + argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN + argsDict["mesh_l2g"] = self.mesh.elementNodesArray + argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] + argsDict["u_trial_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi + argsDict["u_test_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi + argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace + argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace + argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] + argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals + argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians + argsDict["nElements_global"] = self.mesh.nElements_global + argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] + argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, + argsDict["isSeepageFace"] = self.coefficients.isSeepageFace + argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] + argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] + argsDict["rho"] = self.coefficients.rho + argsDict["beta"] = self.coefficients.beta + argsDict["gravity"] = self.coefficients.gravity + argsDict["alpha"] = self.coefficients.vgm_alpha_types + argsDict["n"] = self.coefficients.vgm_n_types + argsDict["thetaR"] = self.coefficients.thetaR_types + argsDict["thetaSR"] = self.coefficients.thetaSR_types + argsDict["KWs"] = self.coefficients.Ksw_types + argsDict["useMetrics"] = 0.0 + argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf + argsDict["lag_shockCapturing"] = 0 + argsDict["shockCapturingDiffusion"] = 0.0 + argsDict["sc_uref"] = 0.0 + argsDict["sc_alpha"] = 0.0 + argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g + argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] + argsDict["elementDiameter"] = self.mesh.elementDiametersArray + argsDict["degree_polynomial"] = degree_polynomial + argsDict["u_dof"] = self.u[0].dof + argsDict["u_dof_old"] = self.u_dof_old + argsDict["velocity"] = self.q['velocity'] + argsDict["q_m"] = self.timeIntegration.m_tmp[0] + argsDict["q_u"] = self.q[('u',0)] + argsDict["q_dV"] = self.q[('dV_u',0)] + argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] + argsDict["cfl"] = self.q[('cfl',0)] + argsDict["q_numDiff_u"] = self.q[('cfl',0)] + argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] + argsDict["offset_u"] = self.offset[0] + argsDict["stride_u"] = self.stride[0] + argsDict["globalResidual"] = r + argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global + argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray + argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray + argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray + argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] + argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] + argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] + argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] + argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] + argsDict["ebqe_phi"] = self.ebqe[('u',0)] + argsDict["epsFact"] = 0.0 + argsDict["ebqe_u"] = self.ebqe[('u',0)] + argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] + argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE + # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION + argsDict["cE"] = self.coefficients.cE + argsDict["cK"] = self.coefficients.cK + # PARAMETERS FOR LOG BASED ENTROPY FUNCTION + argsDict["uL"] = self.coefficients.uL + argsDict["uR"] = self.coefficients.uR + # PARAMETERS FOR EDGE VISCOSITY + argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs + argsDict["NNZ"] = self.nnz + argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern + argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) + argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) + argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms + argsDict["globalJacobian"] = self.jacobian.getCSRrepresentation()[2] + # C matrices + argsDict["Cx"] = Cx + argsDict["Cy"] = Cy + argsDict["Cz"] = Cz + argsDict["CTx"] = CTx + argsDict["CTy"] = CTy + argsDict["CTz"] = CTz + argsDict["ML"] = self.ML + argsDict["delta_x_ij"] = self.delta_x_ij + # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE + argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE + # FLUX CORRECTED TRANSPORT + argsDict["dLow"] = self.dLow + argsDict["fluxMatrix"] = self.fluxMatrix + argsDict["uDotLow"] = self.uDotLow + argsDict["uLow"] = self.uLow + argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL + argsDict["min_s_bc"] = self.min_s_bc + argsDict["max_s_bc"] = self.max_s_bc + argsDict["quantDOFs"] = self.quantDOFs + argsDict["sLow"] = self.sLow + argsDict["sn"] = self.sn + argsDict["anb_seepage_flux_n"]= self.anb_seepage_flux_n +###################################################################################### + argsDict["pn"] = self.u[0].dof + argsDict["solH"] = self.sHigh + + rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() + argsDict["MassMatrix"] = MassMatrix + argsDict["solH"] = self.sHigh + +###################################################################################### + argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #print(anb_seepage_flux) + #argsDict["anb_seepage_flux_n"] = self.coefficients.anb_seepage_flux_n + #if np.sum(anb_seepage_flux_n)>0: + + #logEvent("Hi, this is Arnob", self.anb_seepage_flux_n[0]) + print("Seepage Flux from Python file", np.sum(self.anb_seepage_flux_n)) + seepage_text_variable= np.sum(self.anb_seepage_flux_n) + + with open('seepage_stab_0',"a" ) as f: + #f.write("\n Time"+ ",\t" +"Seepage\n") + #f.write(repr(self.coefficients.t)+ ",\t" +repr(seepage_text_variable), "\n") + f.write(repr(seepage_text_variable)+ "\n") + if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG + self.calculateResidual = self.richards.calculateResidual + self.calculateJacobian = self.richards.calculateJacobian + else: + self.calculateResidual = self.richards.calculateResidual_entropy_viscosity + self.calculateJacobian = self.richards.calculateMassMatrix + if self.delta_x_ij is None: + self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') + self.calculateResidual(argsDict) + #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] + #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf + #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] + #self.timeIntegration.calculateElementCoefficients(self.q) + if self.forceStrongConditions:# + for cj in range(len(self.dirichletConditionsForceDOF)):# + for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): + r[self.offset[cj]+self.stride[cj]*dofN] = 0 + if self.stabilization: + self.stabilization.accumulateSubgridMassHistory(self.q) + logEvent("Global residual",level=9,data=r) + self.nonlinear_function_evaluations += 1 + if self.globalResidualDummy is None: + self.globalResidualDummy = np.zeros(r.shape,'d') + + #print("Hello from the python file", self.coefficients.anb_seepage_flux) + #logEvent("Hello from the python file", self.coefficients.anb_seepage_flux") + + + + + + def invert(self,u,r): + #u=s + #r=p + import pdb + import copy + """ + Calculate the element residuals and add in to the global residual + """ + self.sHigh[:] = u + rowptr, colind, nzval = self.jacobian.getCSRrepresentation() + nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix + r.fill(0.0) + rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() + else: + Cy = np.zeros(Cx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() + else: + Cz = np.zeros(Cx.shape, 'd') + rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() + else: + CTy = np.zeros(CTx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() + else: + CTz = np.zeros(CTx.shape, 'd') + + # This is dummy. I just care about the csr structure of the sparse matrix + nFree = len(rowptr)-1 + degree_polynomial = 1 + try: + degree_polynomial = self.u[0].femSpace.order + except: + pass + if self.delta_x_ij is None: + self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') + argsDict = cArgumentsDict.ArgumentsDict() + argsDict["dt"] = self.timeIntegration.dt + argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi + argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi + argsDict["mesh_dof"] = self.mesh.nodeArray + argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray + argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN + argsDict["mesh_l2g"] = self.mesh.elementNodesArray + argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] + argsDict["u_trial_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi + argsDict["u_test_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi + argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace + argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace + argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] + argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals + argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians + argsDict["nElements_global"] = self.mesh.nElements_global + argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] + argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, + argsDict["isSeepageFace"] = self.coefficients.isSeepageFace + argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] + argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] + argsDict["rho"] = self.coefficients.rho + argsDict["beta"] = self.coefficients.beta + argsDict["gravity"] = self.coefficients.gravity + argsDict["alpha"] = self.coefficients.vgm_alpha_types + argsDict["n"] = self.coefficients.vgm_n_types + argsDict["thetaR"] = self.coefficients.thetaR_types + argsDict["thetaSR"] = self.coefficients.thetaSR_types + argsDict["KWs"] = self.coefficients.Ksw_types + argsDict["useMetrics"] = 0.0 + argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf + argsDict["lag_shockCapturing"] = 0 + argsDict["shockCapturingDiffusion"] = 0.0 + argsDict["sc_uref"] = 0.0 + argsDict["sc_alpha"] = 0.0 + argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g + argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] + argsDict["elementDiameter"] = self.mesh.elementDiametersArray + argsDict["degree_polynomial"] = degree_polynomial + argsDict["u_dof"] = u#self.u[0].dof + argsDict["u_dof_old"] = self.u[0].dof + argsDict["velocity"] = self.q['velocity'] + argsDict["q_m"] = self.timeIntegration.m_tmp[0] + argsDict["q_u"] = self.q[('u',0)] + argsDict["q_dV"] = self.q[('dV_u',0)] + argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] + argsDict["cfl"] = self.q[('cfl',0)] + argsDict["q_numDiff_u"] = self.q[('cfl',0)] + argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] + argsDict["offset_u"] = self.offset[0] + argsDict["stride_u"] = self.stride[0] + argsDict["globalResidual"] = r + argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global + argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray + argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray + argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray + argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] + argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] + argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] + argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] + argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] + argsDict["ebqe_phi"] = self.ebqe[('u',0)] + argsDict["epsFact"] = 0.0 + argsDict["ebqe_u"] = self.ebqe[('u',0)] + argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] + argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE + # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION + argsDict["cE"] = self.coefficients.cE + argsDict["cK"] = self.coefficients.cK + # PARAMETERS FOR LOG BASED ENTROPY FUNCTION + argsDict["uL"] = self.coefficients.uL + argsDict["uR"] = self.coefficients.uR + # PARAMETERS FOR EDGE VISCOSITY + argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs + argsDict["NNZ"] = self.nnz + argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern + argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) + argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) + argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms + # C matrices + argsDict["Cx"] = Cx + argsDict["Cy"] = Cy + argsDict["Cz"] = Cz + argsDict["CTx"] = CTx + argsDict["CTy"] = CTy + argsDict["CTz"] = CTz + argsDict["ML"] = self.ML + argsDict["delta_x_ij"] = self.delta_x_ij + # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE + argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE + # FLUX CORRECTED TRANSPORT + argsDict["dLow"] = self.dLow + argsDict["fluxMatrix"] = self.fluxMatrix + argsDict["uDotLow"] = self.uDotLow + argsDict["uLow"] = self.uLow + argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL + argsDict["min_s_bc"] = self.min_s_bc + argsDict["max_s_bc"] = self.max_s_bc + argsDict["quantDOFs"] = self.quantDOFs + argsDict["sLow"] = self.sLow + argsDict["sn"] = self.sn + #Arnob trying to print flux + argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #print("Hi",anb_seepage_flux) + #print("Hi Seepage Flux", self.coefficients.anb_seepage_flux) + + self.richards.invert(argsDict) + # self.timeIntegration.dt, + # self.u[0].femSpace.elementMaps.psi, + # self.u[0].femSpace.elementMaps.grad_psi, + # self.mesh.nodeArray, + # self.mesh.nodeVelocityArray, + # self.MOVING_DOMAIN, + # self.mesh.elementNodesArray, + # self.elementQuadratureWeights[('u',0)], + # self.u[0].femSpace.psi, + # self.u[0].femSpace.grad_psi, + # self.u[0].femSpace.psi, + # self.u[0].femSpace.grad_psi, + # #element boundary + # self.u[0].femSpace.elementMaps.psi_trace, + # self.u[0].femSpace.elementMaps.grad_psi_trace, + # self.elementBoundaryQuadratureWeights[('u',0)], + # self.u[0].femSpace.psi_trace, + # self.u[0].femSpace.grad_psi_trace, + # self.u[0].femSpace.psi_trace, + # self.u[0].femSpace.grad_psi_trace, + # self.u[0].femSpace.elementMaps.boundaryNormals, + # self.u[0].femSpace.elementMaps.boundaryJacobians, + # #physics + # self.mesh.nElements_global, + # self.ebqe['penalty'],#double* ebqe_penalty_ext, + # self.mesh.elementMaterialTypes,#int* elementMaterialTypes, + # self.coefficients.isSeepageFace, + # self.coefficients.sdInfo[(0,0)][0],#int* a_rowptr, + # self.coefficients.sdInfo[(0,0)][1],#int* a_colind, + # self.coefficients.rho,#double rho, + # self.coefficients.beta,#double beta, + # self.coefficients.gravity,#double* gravity, + # self.coefficients.vgm_alpha_types,#double* alpha, + # self.coefficients.vgm_n_types,#double* n, + # self.coefficients.thetaR_types,#double* thetaR, + # self.coefficients.thetaSR_types,#double* thetaSR, + # self.coefficients.Ksw_types,#double* KWs, + # False,#self.coefficients.useMetrics, + # self.timeIntegration.alpha_bdf, + # 0,#self.shockCapturing.lag, + # 0.0,#cek hack self.shockCapturing.shockCapturingFactor, + # 0.0,#self.coefficients.sc_uref, + # 0.0,#self.coefficients.sc_beta, + # self.u[0].femSpace.dofMap.l2g, + # self.l2g[0]['freeGlobal'], + # self.mesh.elementDiametersArray, + # degree_polynomial, + # self.sHigh, + # self.u_dof_old, + # self.q['velocity'],#self.coefficients.q_v, + # self.timeIntegration.m_tmp[0], + # self.q[('u',0)], + # self.timeIntegration.beta_bdf[0], + # self.q[('cfl',0)], + # self.edge_based_cfl, + # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff[0], + # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff_last[0], + # self.offset[0],self.stride[0], + # r, + # self.mesh.nExteriorElementBoundaries_global, + # self.mesh.exteriorElementBoundariesArray, + # self.mesh.elementBoundaryElementsArray, + # self.mesh.elementBoundaryLocalElementBoundariesArray, + # self.ebqe['velocity'],#self.coefficients.ebqe_v, + # self.numericalFlux.isDOFBoundary[0], + # self.numericalFlux.ebqe[('u',0)], + # self.ebqe[('advectiveFlux_bc_flag',0)], + # self.ebqe[('advectiveFlux_bc',0)], + # self.ebqe[('u',0)],#cek hack self.coefficients.ebqe_phi, + # 0.0,#cek hack self.coefficients.epsFact, + # self.ebqe[('u',0)], + # self.ebqe[('advectiveFlux',0)], + # # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION + # self.coefficients.cE, + # self.coefficients.cK, + # # PARAMETERS FOR LOG BASED ENTROPY FUNCTION + # self.coefficients.uL, + # self.coefficients.uR, + # # PARAMETERS FOR EDGE VISCOSITY + # len(rowptr) - 1, # num of DOFs + # len(Cx), # num of non-zero entries in the sparsity pattern + # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) + # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) + # self.csrRowIndeces[(0, 0)], # row indices (convenient for element loops) + # self.csrColumnOffsets[(0, 0)], # column indices (convenient for element loops) + # self.csrColumnOffsets_eb[(0, 0)], # indices for boundary terms + # # C matrices + # Cx, + # Cy, + # Cz, + # CTx, + # CTy, + # CTz, + # self.ML, + # self.delta_x_ij, + # # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + # self.coefficients.LUMPED_MASS_MATRIX, + # self.coefficients.STABILIZATION_TYPE, + # self.coefficients.ENTROPY_TYPE, + # # FLUX CORRECTED TRANSPORT + # self.dLow, + # self.fluxMatrix, + # self.uDotLow, + # self.uLow, + # self.dt_times_dC_minus_dL, + # self.min_s_bc, + # self.max_s_bc, + # self.quantDOFs) + #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] + #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf + #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] + #self.timeIntegration.calculateElementCoefficients(self.q) + #if self.forceStrongConditions:# + # for cj in range(len(self.dirichletConditionsForceDOF)):# + # for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): + # r[self.offset[cj]+self.stride[cj]*dofN] = 0 + #if self.stabilization: + # self.stabilization.accumulateSubgridMassHistory(self.q) + #logEvent("Global residual",level=9,data=r) + #self.nonlinear_function_evaluations += 1 + #if self.globalResidualDummy is None: + # self.globalResidualDummy = numpy.zeros(r.shape,'d') + def postStep(self, t, firstStep=False): + with open('seepage_flux_nnnn', "a") as f: + f.write("\n Time"+ ",\t" +"Seepage\n") + f.write(repr(t)+ ",\t" +repr(self.coefficients.anb_seepage_flux)) + def getJacobian(self,jacobian): + if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG + cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, + jacobian) + degree_polynomial = 1 + try: + degree_polynomial = self.u[0].femSpace.order + except: + pass + if self.delta_x_ij is None: + self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') + argsDict = cArgumentsDict.ArgumentsDict() + argsDict["dt"] = self.timeIntegration.dt + argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi + argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi + argsDict["mesh_dof"] = self.mesh.nodeArray + argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray + argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN + argsDict["mesh_l2g"] = self.mesh.elementNodesArray + argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] + argsDict["u_trial_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi + argsDict["u_test_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi + argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace + argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace + argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] + argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals + argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians + argsDict["nElements_global"] = self.mesh.nElements_global + argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] + argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, + argsDict["isSeepageFace"] = self.coefficients.isSeepageFace + argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] + argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] + argsDict["rho"] = self.coefficients.rho + argsDict["beta"] = self.coefficients.beta + argsDict["gravity"] = self.coefficients.gravity + argsDict["alpha"] = self.coefficients.vgm_alpha_types + argsDict["n"] = self.coefficients.vgm_n_types + argsDict["thetaR"] = self.coefficients.thetaR_types + argsDict["thetaSR"] = self.coefficients.thetaSR_types + argsDict["KWs"] = self.coefficients.Ksw_types + argsDict["useMetrics"] = 0.0 + argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf + argsDict["lag_shockCapturing"] = 0 + argsDict["shockCapturingDiffusion"] = 0.0 + argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g + argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] + argsDict["elementDiameter"] = self.mesh.elementDiametersArray + argsDict["degree_polynomial"] = degree_polynomial + argsDict["u_dof"] = self.u[0].dof + argsDict["velocity"] = self.q['velocity'] + argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] + argsDict["cfl"] = self.q[('cfl',0)] + argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] + argsDict["csrRowIndeces_u_u"] = self.csrRowIndeces[(0,0)] + argsDict["csrColumnOffsets_u_u"] = self.csrColumnOffsets[(0,0)] + argsDict["globalJacobian"] = jacobian.getCSRrepresentation()[2] + argsDict["delta_x_ij"] = self.delta_x_ij + argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global + argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray + argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray + argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray + argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] + argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] + argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] + argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] + argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] + argsDict["csrColumnOffsets_eb_u_u"] = self.csrColumnOffsets_eb[(0,0)] + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + + #arnob trying to calculate flux + #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #Arnob trying to print flux + #argsDict["anb_seepage_flux"] = self.calculateResidual.anb_seepage_flux + + #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #print("Hi Seepage Flux", self.coefficients.anb_seepage_flux) + #print("Hi Seepage Flux",anb_seepage_flux) + #print("The seepage is ", anb_seepage_flux) + + + + + self.calculateJacobian(argsDict) + if self.forceStrongConditions: + for dofN in list(self.dirichletConditionsForceDOF[0].DOFBoundaryConditionsDict.keys()): + global_dofN = self.offset[0]+self.stride[0]*dofN + self.nzval[np.where(self.colind == global_dofN)] = 0.0 #column + self.nzval[self.rowptr[global_dofN]:self.rowptr[global_dofN+1]] = 0.0 #row + zeroRow=True + for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]):#row + if (self.colind[i] == global_dofN): + self.nzval[i] = 1.0 + zeroRow = False + if zeroRow: + raise RuntimeError("Jacobian has a zero row because sparse matrix has no diagonal entry at row "+repr(global_dofN)+". You probably need add diagonal mass or reaction term") + #scaling = 1.0#probably want to add some scaling to match non-dirichlet diagonals in linear system + #for cj in range(self.nc): + # for dofN in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.keys()): + # global_dofN = self.offset[cj]+self.stride[cj]*dofN + # for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]): + # if (self.colind[i] == global_dofN): + # self.nzval[i] = scaling + # else: + # self.nzval[i] = 0.0 + logEvent("Jacobian ",level=10,data=jacobian) + #mwf decide if this is reasonable for solver statistics + self.nonlinear_function_jacobian_evaluations += 1 + return jacobian + def calculateElementQuadrature(self): + """ + Calculate the physical location and weights of the quadrature rules + and the shape information at the quadrature points. + + This function should be called only when the mesh changes. + """ + #self.u[0].femSpace.elementMaps.getValues(self.elementQuadraturePoints, + # self.q['x']) + self.u[0].femSpace.elementMaps.getBasisValuesRef(self.elementQuadraturePoints) + self.u[0].femSpace.elementMaps.getBasisGradientValuesRef(self.elementQuadraturePoints) + self.u[0].femSpace.getBasisValuesRef(self.elementQuadraturePoints) + self.u[0].femSpace.getBasisGradientValuesRef(self.elementQuadraturePoints) + self.coefficients.initializeElementQuadrature(self.timeIntegration.t,self.q) + if self.stabilization != None: + self.stabilization.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) + self.stabilization.initializeTimeIntegration(self.timeIntegration) + if self.shockCapturing != None: + self.shockCapturing.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) + def calculateElementBoundaryQuadrature(self): + pass + def calculateExteriorElementBoundaryQuadrature(self): + """ + Calculate the physical location and weights of the quadrature rules + and the shape information at the quadrature points on global element boundaries. + + This function should be called only when the mesh changes. + """ + # + #get physical locations of element boundary quadrature points + # + #assume all components live on the same mesh + self.u[0].femSpace.elementMaps.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.elementMaps.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.elementMaps.getValuesGlobalExteriorTrace(self.elementBoundaryQuadraturePoints, + self.ebqe['x']) + self.fluxBoundaryConditionsObjectsDict = dict([(cj,FluxBoundaryConditions(self.mesh, + self.nElementBoundaryQuadraturePoints_elementBoundary, + self.ebqe[('x')], + getAdvectiveFluxBoundaryConditions=self.advectiveFluxBoundaryConditionsSetterDict[cj], + getDiffusiveFluxBoundaryConditions=self.diffusiveFluxBoundaryConditionsSetterDictDict[cj])) + for cj in list(self.advectiveFluxBoundaryConditionsSetterDict.keys())]) + self.coefficients.initializeGlobalExteriorElementBoundaryQuadrature(self.timeIntegration.t,self.ebqe) + #argsDict = cArgumentsDict.ArgumentsDict() + #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #print("Hi", self.coefficients.anb_seepage_flux) + + #print("The seepage is ", anb_seepage_flux) + def estimate_mt(self): + pass + def calculateSolutionAtQuadrature(self): + pass + def calculateAuxiliaryQuantitiesAfterStep(self): + pass + def postStep(self, t, firstStep=False): + with open('seepage_flux_nnnnk', "a") as f: + f.write("\n Time"+ ",\t" +"Seepage\n") + f.write(repr(t)+ ",\t" +repr(self.coefficients.anb_seepage_flux)) + + + +#argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux +#anb_seepage_flux= self.coefficients.anb_seepage_flux +#print("Hi",anb_seepage_flux) + + +#print("Hello from the python file", self.coefficients.anb_seepage_flux) diff --git a/richards_fct/richards/Richards_new.h b/richards_fct/richards/Richards_new.h new file mode 100644 index 0000000000..d9e6a76a4a --- /dev/null +++ b/richards_fct/richards/Richards_new.h @@ -0,0 +1,2966 @@ +#ifndef Richards_H +#define Richards_H +#include +#include +#include +#include "CompKernel.h" +#include "ModelFactory.h" +#include "../mprans/ArgumentsDict.h" +#include "xtensor-python/pyarray.hpp" +#define nnz nSpace + +namespace py = pybind11; +#define POWER_SMOOTHNESS_INDICATOR 2 +#define IS_BETAij_ONE 0 +#define GLOBAL_FCT 0 +namespace proteus +{ + // Power entropy // + inline double ENTROPY(const double& phi, const double& phiL, const double& phiR){ + return 1./2.*std::pow(fabs(phi),2.); + } + inline double DENTROPY(const double& phi, const double& phiL, const double& phiR){ + return fabs(phi)*(phi>=0 ? 1 : -1); + } + // Log entropy // for level set from 0 to 1 + inline double ENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ + return std::log(fabs((phi-phiL)*(phiR-phi))+1E-14); + } + inline double DENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ + return (phiL+phiR-2*phi)*((phi-phiL)*(phiR-phi)>=0 ? 1 : -1)/(fabs((phi-phiL)*(phiR-phi))+1E-14); + } +} + +namespace proteus +{ + class Richards_base + { + //The base class defining the interface + public: + virtual ~Richards_base(){} + virtual void calculateResidual(arguments_dict& args)=0; + virtual void calculateJacobian(arguments_dict& args)=0; + virtual void invert(arguments_dict& args)=0; + virtual void FCTStep(arguments_dict& args)=0; + virtual void kth_FCT_step(arguments_dict& args)=0; + virtual void calculateResidual_entropy_viscosity(arguments_dict& args)=0; + virtual void calculateMassMatrix(arguments_dict& args)=0; + }; + + template + class Richards : public Richards_base + { + public: + const int nDOF_test_X_trial_element; + CompKernelType ck; + Richards(): + nDOF_test_X_trial_element(nDOF_test_element*nDOF_trial_element), + ck() + {} + inline + void evaluateCoefficients(const int rowptr[nSpace], + const int colind[nnz], + const double rho, + const double beta, + const double gravity[nSpace], + const double alpha, + const double n_vg, + const double thetaR, + const double thetaSR, + const double KWs[nnz], + const double& u, + double& m, + double& dm, + double f[nSpace], + double df[nSpace], + double a[nnz], + double da[nnz], + double as[nnz], + double& kr, + double& dkr) + { + const int nSpace2 = nSpace * nSpace; + double psiC; + double pcBar; + double pcBar_n; + double pcBar_nM1; + double pcBar_nM2; + double onePlus_pcBar_n; + double sBar; + double sqrt_sBar; + double DsBar_DpsiC; + double thetaW; + double DthetaW_DpsiC; + double vBar; + double vBar2; + double DvBar_DpsiC; + double KWr; + double DKWr_DpsiC; + double rho2 = rho * rho; + double thetaS; + double rhom; + double drhom; + double m_vg; + double pcBarStar; + double sqrt_sBarStar; + + psiC = -u; + m_vg = 1.0 - 1.0 / n_vg; + thetaS = thetaR + thetaSR; + if (psiC > 0.0) + { + pcBar = alpha * psiC; + pcBarStar = pcBar; + if (pcBar < 1.0e-8) + pcBarStar = 1.0e-8; + pcBar_nM2 = pow(pcBarStar, n_vg - 2); + pcBar_nM1 = pcBar_nM2 * pcBar; + pcBar_n = pcBar_nM1 * pcBar; + onePlus_pcBar_n = 1.0 + pcBar_n; + + sBar = pow(onePlus_pcBar_n, -m_vg); + /* using -mn = 1-n */ + DsBar_DpsiC = alpha * (1.0 - n_vg) * (sBar/onePlus_pcBar_n)*pcBar_nM1; + + vBar = 1.0-pcBar_nM1*sBar; + vBar2 = vBar*vBar; + DvBar_DpsiC = -alpha*(n_vg-1.0)*pcBar_nM2*sBar - pcBar_nM1*DsBar_DpsiC; + + thetaW = thetaSR*sBar + thetaR; + DthetaW_DpsiC = thetaSR * DsBar_DpsiC; + + sqrt_sBar = sqrt(sBar); + sqrt_sBarStar = sqrt_sBar; + if (sqrt_sBar < 1.0e-8) + sqrt_sBarStar = 1.0e-8; + KWr= sqrt_sBar*vBar2; + DKWr_DpsiC= ((0.5/sqrt_sBarStar)*DsBar_DpsiC*vBar2 + + + 2.0*sqrt_sBar*vBar*DvBar_DpsiC); + } + else + { + thetaW = thetaS; + DthetaW_DpsiC = 0.0; + KWr = 1.0; + DKWr_DpsiC = 0.0; + } + //slight compressibility + rhom = rho*exp(beta*u); + drhom = beta*rhom; + m = rhom*thetaW; + dm = -rhom*DthetaW_DpsiC+drhom*thetaW; + for (int I=0;I thetaS || thetaW <= thetaR) + { + //cek debug + std::cout<<"rho "< 0.0) + { + isDOFBoundary = 1; + bc_u = bc_u_seepage; + } + else + { + isDOFBoundary = 0; + flux = 0.0; + } + } + /* //set DOF flag and flux correctly if seepage face */ + /* if (isSeepageFace) */ + /* { */ + /* if (flux < 0.0 || u < bc_u_seepage) */ + /* { */ + /* isDOFBoundary = 0; */ + /* flux = 0.0; */ + /* } */ + /* else */ + /* { */ + /* isDOFBoundary = 1; */ + /* bc_u = bc_u_seepage; */ + /* } */ + /* } */ + /* //Dirichlet penalty */ + /* if (isDOFBoundary) */ + /* flux += penalty*(u-bc_u); */ + } + else + flux = bc_flux; + } + + void exteriorNumericalFluxJacobian(const int rowptr[nSpace], + const int colind[nnz], + const int isDOFBoundary, + const double n[nSpace], + const double K[nnz], + const double dK[nnz], + const double grad_psi[nSpace], + const double grad_v[nSpace], + const double dK_rho_g[nSpace], + const double v, + const double penalty, + double& fluxJacobian) + { + if (isDOFBoundary) + { + fluxJacobian = 0.0; + for(int I=0;I& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + double sc_uref = args.scalar("sc_uref"); + double sc_alpha = args.scalar("sc_alpha"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& u_dof_old = args.array("u_dof_old"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m = args.array("q_m"); + xt::pyarray& q_u = args.array("q_u"); + xt::pyarray& q_dV = args.array("q_dV"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + int offset_u = args.scalar("offset_u"); + int stride_u = args.scalar("stride_u"); + xt::pyarray& globalResidual = args.array("globalResidual"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& ebqe_phi = args.array("ebqe_phi"); + double epsFact = args.scalar("epsFact"); + xt::pyarray& ebqe_u = args.array("ebqe_u"); + xt::pyarray& ebqe_flux = args.array("ebqe_flux"); + // PARAMETERS FOR EDGE BASED STABILIZATION + double cE = args.scalar("cE"); + double cK = args.scalar("cK"); + // PARAMETERS FOR LOG BASED ENTROPY FUNCTION + double uL = args.scalar("uL"); + double uR = args.scalar("uR"); + // PARAMETERS FOR EDGE VISCOSITY + int numDOFs = args.scalar("numDOFs"); + int NNZ = args.scalar("NNZ"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); + xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); + xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); + xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); + // C matrices + xt::pyarray& Cx = args.array("Cx"); + xt::pyarray& Cy = args.array("Cy"); + xt::pyarray& Cz = args.array("Cz"); + xt::pyarray& CTx = args.array("CTx"); + xt::pyarray& CTy = args.array("CTy"); + xt::pyarray& CTz = args.array("CTz"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); + int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); + // FOR FCT + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& fluxMatrix = args.array("fluxMatrix"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); + xt::pyarray& min_s_bc = args.array("min_s_bc"); + xt::pyarray& max_s_bc = args.array("max_s_bc"); + // AUX QUANTITIES OF INTEREST + xt::pyarray& quantDOFs = args.array("quantDOFs"); + xt::pyarray& sLow = args.array("sLow"); + xt::pyarray& sn = args.array("sn"); + + assert(a_rowptr.data()[nSpace] == nnz); + assert(a_rowptr.data()[nSpace] == nSpace); + //cek should this be read in? + double Ct_sge = 4.0; + + //loop over elements to compute volume integrals and load them into element and global residual + // + //eN is the element index + //eN_k is the quadrature point index for a scalar + //eN_k_nSpace is the quadrature point index for a vector + //eN_i is the element test function index + //eN_j is the element trial function index + //eN_k_j is the quadrature point index for a trial function + //eN_k_i is the quadrature point index for a trial function + for(int eN=0;eN& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); + xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); + xt::pyarray& globalJacobian = args.array("globalJacobian"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + assert(a_rowptr.data()[nSpace] == nnz); + assert(a_rowptr.data()[nSpace] == nSpace); + double Ct_sge = 4.0; + + // + //loop over elements to compute volume integrals and load them into the element Jacobians and global Jacobian + // + for(int eN=0;eN& bc_mask = args.array("bc_mask"); + int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern + int numDOFs = args.scalar("numDOFs"); //number of DOFs + double dt = args.scalar("dt"); + xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) + xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn + xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn + xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& limited_solution = args.array("limited_solution"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets + xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices + xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 + xt::pyarray& max_s_bc = args.array("max_s_bc"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int MONOLITHIC = args.scalar("MONOLITHIC"); + register double Rpos[numDOFs], Rneg[numDOFs]; + register double FluxCorrectionMatrix[NNZ]; + register double solL[numDOFs]; + register double sdot[numDOFs]; + ////////////////// + // LOOP in DOFs // + ////////////////// + int ij=0; + for (int i=0; i 0) ? 1. : 0.); + Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); + + //update ij + ij+=1; + //std::cout<<"sdoti error"<0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])) + * FluxCorrectionMatrix[ij]; + alpha_dot = fmin(1.0, beta_ij*fabs(alpha_fA)/MassMatrix.data()[ij]/fmax(1.0e-8,fabs(sdoti-sdotj))); + if (MONOLITHIC == 0) + { + ith_Limiter_times_FluxCorrectionMatrix += alpha_fA; + } + else + { + ith_Limiter_times_FluxCorrectionMatrix += alpha_fA + (LUMPED_MASS_MATRIX == 1 ? 0. : 1.)*dt*alpha_dot*MassMatrix.data()[ij]*(sdoti-sdotj); + } + //update ij + ij+=1; + } + limited_solution.data()[i] = solL[i] + 1./lumped_mass_matrix.data()[i]*ith_Limiter_times_FluxCorrectionMatrix*bc_mask[i]; + } + } + + void kth_FCT_step(arguments_dict& args) + { + int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern + int numDOFs = args.scalar("numDOFs"); //number of DOFs + int num_fct_iter = args.scalar("num_fct_iter"); + double dt = args.scalar("dt"); + xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) + xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn + xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn + xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& solLim = args.array("limited_solution"); + xt::pyarray& MC = args.array("MC"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& FluxMatrix = args.array("FluxMatrix"); + xt::pyarray& limitedFlux = args.array("limited_Flux"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets + xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices + xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 + xt::pyarray& max_s_bc = args.array("max_s_bc"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int MONOLITHIC = args.scalar("MONOLITHIC"); + register double Rpos[numDOFs], Rneg[numDOFs]; + int ij=0; + + ////////////////////////////////////////////////////// + // ********** COMPUTE LOW ORDER SOLUTION ********** // + ////////////////////////////////////////////////////// + if (num_fct_iter == 0) + { // No FCT for global bounds + for (int i=0; i 0) ? 1. : 0.); + // update ij + ij+=1; + } + // compute Q vectors + double mi = ML.data()[i]; + double solLimi = solLim.data()[i]; + double Qposi = mi*(maxi-solLimi); + // compute R vectors + Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + } + ij=0; + for (int i=0; i0 ? Rposi : Rpos[j]); + // compute limited flux + ith_Limiter_times_FluxCorrectionMatrix += Lij*Fluxij; + + // update limited flux + limitedFlux.data()[ij] = Lij*Fluxij; + + //update FluxMatrix + FluxMatrix.data()[ij] = Fluxij; + + //update ij + ij+=1; + } + //update limited solution + double mi = ML.data()[i]; + solLim.data()[i] += 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; + } + } + } + + // ***************************************** // + // ********** HIGH ORDER SOLUTION ********** // + // ***************************************** // + ij=0; + for (int i=0; i 0 ? 1. : 0.); + Pnegi += fij * (fij < 0 ? 1. : 0.); + //update ij + ij+=1; + } + // compute Q vectors // + double mi = ML.data()[i]; + double Qposi = mi*(maxi-solLim.data()[i]); + double Qnegi = mi*(mini-solLim.data()[i]); + // compute R vectors // + Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); + } + + // COMPUTE LIMITERS // + ij=0; + for (int i=0; i 0 ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j]); + // compute ith_limited_flux_correction + ith_limited_flux_correction += Lij*fij; + ij+=1; + } + double mi = ML.data()[i]; + solLim[i] += 1./mi*ith_limited_flux_correction; + } + } + + void calculateResidual_entropy_viscosity(arguments_dict& args) + { + xt::pyarray& globalJacobian = args.array("globalJacobian"); + double Theta = args.scalar("Theta"); + xt::pyarray& bc_mask = args.array("bc_mask"); + double dt = args.scalar("dt"); + xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + double sc_uref = args.scalar("sc_uref"); + double sc_alpha = args.scalar("sc_alpha"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& r_l2g = args.array("r_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + int degree_polynomial = args.scalar("degree_polynomial"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& u_dof_old = args.array("u_dof_old"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m = args.array("q_m"); + xt::pyarray& q_u = args.array("q_u"); + xt::pyarray& q_dV = args.array("q_dV"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + int offset_u = args.scalar("offset_u"); + int stride_u = args.scalar("stride_u"); + xt::pyarray& globalResidual = args.array("globalResidual"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& ebqe_phi = args.array("ebqe_phi"); + double epsFact = args.scalar("epsFact"); + xt::pyarray& ebqe_u = args.array("ebqe_u"); + xt::pyarray& ebqe_flux = args.array("ebqe_flux"); + // PARAMETERS FOR EDGE BASED STABILIZATION + double cE = args.scalar("cE"); + double cK = args.scalar("cK"); + // PARAMETERS FOR LOG BASED ENTROPY FUNCTION + double uL = args.scalar("uL"); + double uR = args.scalar("uR"); + // PARAMETERS FOR EDGE VISCOSITY + int numDOFs = args.scalar("numDOFs"); + int NNZ = args.scalar("NNZ"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); + xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); + xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); + xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); + // C matrices + xt::pyarray& Cx = args.array("Cx"); + xt::pyarray& Cy = args.array("Cy"); + xt::pyarray& Cz = args.array("Cz"); + xt::pyarray& CTx = args.array("CTx"); + xt::pyarray& CTy = args.array("CTy"); + xt::pyarray& CTz = args.array("CTz"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); + int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); + // FOR FCT + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& fluxMatrix = args.array("fluxMatrix"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); + xt::pyarray& min_s_bc = args.array("min_s_bc"); + xt::pyarray& max_s_bc = args.array("max_s_bc"); + // AUX QUANTITIES OF INTEREST + xt::pyarray& quantDOFs = args.array("quantDOFs"); + xt::pyarray& sLow = args.array("sLow"); + xt::pyarray& sn = args.array("sn"); + register double Rpos[numDOFs], Rneg[numDOFs]; + //register double FluxCorrectionMatrix[NNZ]; + // NOTE: This function follows a different (but equivalent) implementation of the smoothness based indicator than NCLS.h + // Allocate space for the transport matrices + // This is used for first order KUZMIN'S METHOD + register double TransportMatrix[NNZ],TransportMatrixConsistent[NNZ]; + register double TransportMatrixn[NNZ],TransportMatrixConsistentn[NNZ]; + std::valarray u_free_dof(numDOFs); + std::valarray u_free_dof_old(numDOFs); + std::valarray ML2(numDOFs); + for(int eN=0;eN= 0 && isFluxBoundary_u[ebNE_kb] != 1 ) //outflow. This is handled via the transport matrices. Then flux_ext=0 and dflux_ext!=0 */ + /* { */ + /* dflux_ext = flow; */ + /* flux_ext = 0; */ + /* // save external u */ + /* ebqe_u[ebNE_kb] = u_ext; */ + /* } */ + /* else // inflow. This is handled via the boundary integral. Then flux_ext!=0 and dflux_ext=0 */ + /* { */ + /* dflux_ext = 0; */ + /* // save external u */ + /* ebqe_u[ebNE_kb] = isDOFBoundary_u[ebNE_kb]*ebqe_bc_u_ext[ebNE_kb]+(1-isDOFBoundary_u[ebNE_kb])*u_ext; */ + /* if (isDOFBoundary_u[ebNE_kb] == 1) */ + /* flux_ext = ebqe_bc_u_ext[ebNE_kb]*flow; */ + /* else if (isFluxBoundary_u[ebNE_kb] == 1) */ + /* flux_ext = ebqe_bc_flux_u_ext[ebNE_kb]; */ + /* else */ + /* { */ + /* std::cout<<"warning: VOF open boundary with no external trace, setting to zero for inflow"<= 0.) + { + alpha_numerator_pos += alpha_num; + alpha_denominator_pos += alpha_num; + } + else + { + alpha_numerator_neg += alpha_num; + alpha_denominator_neg += fabs(alpha_num); + } + //update ij + ij+=1; + } + // scale g vector by lumped mass matrix + if (fabs(ML.data()[i] - ML2[i]) > 1.0e-16) + std::cout<<"ML "< 0.0) + // assert( (xi[I] - xj[I]) == delta_x_ij[offset*3+I]); + //gi_times_x += gi[I]*(xi[I]-xj[I]); + gi_times_x += gi[I]*delta_x_ij.data()[offset*3+I]; + } + // compute the positive and negative part of gi*(xi-xj) + SumPos += gi_times_x > 0 ? gi_times_x : 0; + SumNeg += gi_times_x < 0 ? gi_times_x : 0; + } + double sigmaPosi = fmin(1.,(fabs(SumNeg)+1E-15)/(SumPos+1E-15)); + double sigmaNegi = fmin(1.,(SumPos+1E-15)/(fabs(SumNeg)+1E-15)); + double alpha_numi = fabs(sigmaPosi*alpha_numerator_pos + sigmaNegi*alpha_numerator_neg); + double alpha_deni = sigmaPosi*alpha_denominator_pos + sigmaNegi*alpha_denominator_neg; + if (IS_BETAij_ONE == 1) + { + alpha_numi = fabs(alpha_numerator_pos + alpha_numerator_neg); + alpha_deni = alpha_denominator_pos + alpha_denominator_neg; + } + double alphai = alpha_numi/(alpha_deni+1E-15); + quantDOFs.data()[i] = alphai; + + if (POWER_SMOOTHNESS_INDICATOR==0) + psi[i] = 1.0; + else + psi[i] = std::pow(alphai,POWER_SMOOTHNESS_INDICATOR); //NOTE: they use alpha^2 in the paper + } + ///////////////////////////////////////////// + // ** LOOP IN DOFs FOR EDGE BASED TERMS ** // + ///////////////////////////////////////////// + ij=0; + for (int i=0; i Dissipation matrices as well. + double soli = u_free_dof[i]; // solution at time tn for the ith DOF + double solni = u_free_dof_old[i]; // solution at time tn for the ith DOF + for (int I=0;I mMax) + { + std::cout<<"mass out of bounds "< 0) ? 1. : 0.); + // Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); + // ij+=1; + // } + // double mi = ML[i]; + // double solni = u_dof_old[i]; + // double Qposi = mi*(maxi-solni); + // double Qnegi = mi*(mini-solni); + + //std::cout << Qposi << std::endl; + // Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + // Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); + + //if (Rpos[i] < 0) + //{ + // std::cout << mi << "\t" << maxi << "\t" << solni << std::endl; + // std::cout << Qposi << "\t" << Pposi << std::endl; + // std::cout << Rpos[i] << std::endl; + //abort(); + //} + //} + + //ij=0; + //for (int i=0; i 1.0 || Rposi < 0.0) + //std::cout << "Rposi: " << Rposi << std::endl; + //if (Rnegi > 1.0 || Rnegi < 0.0) + //std::cout << "Rnegi: " << Rnegi << std::endl; + + // LOOP OVER THE SPARSITY PATTERN (j-LOOP)// + // for (int offset=csrRowIndeces_DofLoops.data()[i]; + // offset0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])); + // //Lij=0.0; + // ith_Limiter_times_FluxCorrectionMatrix += Lij*FluxCorrectionMatrix[ij]; + // //update ij + // ij+=1; + // } + // double mi = ML[i]; + // double solni = u_dof_old[i]; + // globalResidual[i] = solni + 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; + //} + + } + + void invert(arguments_dict& args) + { + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + xt::pyarray& globalResidual = args.array("globalResidual"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + int numDOFs = args.scalar("numDOFs"); + for (int i=0; i mMax) + { + std::cout<<"mass out of bounds "<("dt"); + xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + //element boundary + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + //physics + int nElements_global = args.scalar("nElements_global"); + //new + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + //end new + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& r_l2g = args.array("r_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + int degree_polynomial = args.scalar("degree_polynomial"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); + xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); + xt::pyarray& globalJacobian = args.array("globalJacobian"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + //std::cout<<"ndjaco address "<(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + else if (nSpaceIn == 2) + return proteus::chooseAndAllocateDiscretization2D(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + else + { + assert(nSpaceIn == 3); + return proteus::chooseAndAllocateDiscretization(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + } + } +}//proteus +#endif diff --git a/richards_fct/richards/Richards_new.py b/richards_fct/richards/Richards_new.py new file mode 100644 index 0000000000..841fcd0884 --- /dev/null +++ b/richards_fct/richards/Richards_new.py @@ -0,0 +1,1745 @@ +from __future__ import division +from builtins import range +from past.utils import old_div +import proteus +from .cRichards import * +import numpy as np +from proteus.Transport import OneLevelTransport +from proteus.Transport import TC_base, NonlinearEquation, logEvent, memory +from proteus.Transport import FluxBoundaryConditions, Comm, cfemIntegrals +from proteus.Transport import DOFBoundaryConditions, Quadrature +from proteus.mprans import cArgumentsDict +from proteus.LinearAlgebraTools import SparseMat +from proteus import TimeIntegration +from proteus.NonlinearSolvers import ExplicitLumpedMassMatrixForRichards + +class ThetaScheme(TimeIntegration.BackwardEuler): + def __init__(self,transport,integrateInterpolationPoints=False): + self.transport=transport + TimeIntegration.BackwardEuler.__init__(self,transport, integrateInterpolationPoints) + def updateTimeHistory(self,resetFromDOF=False): + TimeIntegration.BackwardEuler.updateTimeHistory(self,resetFromDOF) + self.transport.u_dof_old[:] = self.u +class RKEV(TimeIntegration.SSP): + from proteus import TimeIntegration + """ + Wrapper for SSPRK time integration using EV + + ... more to come ... + """ + + def __init__(self, transport, timeOrder=1, runCFL=0.1, integrateInterpolationPoints=False): + TimeIntegration.SSP.__init__(self, transport, integrateInterpolationPoints=integrateInterpolationPoints) + self.runCFL = runCFL + self.dtLast = None + self.isAdaptive = True + # About the cfl + assert transport.coefficients.STABILIZATION_TYPE > 0, "SSP method just works for edge based EV methods; i.e., STABILIZATION_TYPE>0" + assert hasattr(transport, 'edge_based_cfl'), "No edge based cfl defined" + self.cfl = transport.edge_based_cfl + # Stuff particular for SSP + self.timeOrder = timeOrder # order of approximation + self.nStages = timeOrder # number of stages total + self.lstage = 0 # last stage completed + # storage vectors + self.u_dof_last = {} + # per component stage values, list with array at each stage + self.u_dof_stage = {} + for ci in range(self.nc): + if ('m', ci) in transport.q: + self.u_dof_last[ci] = transport.u[ci].dof.copy() + self.u_dof_stage[ci] = [] + for k in range(self.nStages + 1): + self.u_dof_stage[ci].append(transport.u[ci].dof.copy()) + + # def set_dt(self, DTSET): + # self.dt = DTSET # don't update t + def choose_dt(self): + comm = Comm.get() + maxCFL = 1.0e-6 + maxCFL = max(maxCFL, comm.globalMax(self.cfl.max())) + self.dt = old_div(self.runCFL, maxCFL) + if self.dtLast is None: + self.dtLast = self.dt + self.t = self.tLast + self.dt + self.substeps = [self.t for i in range(self.nStages)] # Manuel is ignoring different time step levels for now + + def initialize_dt(self, t0, tOut, q): + """ + Modify self.dt + """ + self.tLast = t0 + self.choose_dt() + self.t = t0 + self.dt + + def setCoefficients(self): + """ + beta are all 1's here + mwf not used right now + """ + self.alpha = np.zeros((self.nStages, self.nStages), 'd') + self.dcoefs = np.zeros((self.nStages), 'd') + + def updateStage(self): + """ + Need to switch to use coefficients + """ + self.lstage += 1 + assert self.timeOrder in [1, 2, 3] + assert self.lstage > 0 and self.lstage <= self.timeOrder + if self.timeOrder == 3: + if self.lstage == 1: + logEvent("First stage of SSP33 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + # update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] + elif self.lstage == 2: + logEvent("Second stage of SSP33 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + self.u_dof_stage[ci][self.lstage] *= old_div(1., 4.) + self.u_dof_stage[ci][self.lstage] += 3. / 4. * self.u_dof_last[ci] + # Update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] + elif self.lstage == 3: + logEvent("Third stage of SSP33 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + self.u_dof_stage[ci][self.lstage] *= old_div(2.0, 3.0) + self.u_dof_stage[ci][self.lstage] += 1.0 / 3.0 * self.u_dof_last[ci] + # update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_last[ci] + # update solution to u[0].dof + self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] + elif self.timeOrder == 2: + if self.lstage == 1: + logEvent("First stage of SSP22 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + # Update u_dof_old + self.transport.u_dof_old[:] = self.transport.u[ci].dof + elif self.lstage == 2: + logEvent("Second stage of SSP22 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + self.u_dof_stage[ci][self.lstage][:] *= old_div(1., 2.) + self.u_dof_stage[ci][self.lstage][:] += 1. / 2. * self.u_dof_last[ci] + # update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_last[ci] + # update solution to u[0].dof + self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] + else: + assert self.timeOrder == 1 + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof[:] + self.transport.u_dof_old[:] = self.transport.u[ci].dof + + def initializeTimeHistory(self, resetFromDOF=True): + """ + Push necessary information into time history arrays + """ + for ci in range(self.nc): + self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] + for k in range(self.nStages): + self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] + + def updateTimeHistory(self, resetFromDOF=False): + """ + assumes successful step has been taken + """ + + self.t = self.tLast + self.dt + for ci in range(self.nc): + self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] + for k in range(self.nStages): + self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] + self.lstage = 0 + self.dtLast = self.dt + self.tLast = self.t + + def generateSubsteps(self, tList): + """ + create list of substeps over time values given in tList. These correspond to stages + """ + self.substeps = [] + tLast = self.tLast + for t in tList: + dttmp = t - tLast + self.substeps.extend([tLast + dttmp for i in range(self.nStages)]) + tLast = t + + def resetOrder(self, order): + """ + initialize data structures for stage updges + """ + self.timeOrder = order # order of approximation + self.nStages = order # number of stages total + self.lstage = 0 # last stage completed + # storage vectors + # per component stage values, list with array at each stage + self.u_dof_stage = {} + for ci in range(self.nc): + if ('m', ci) in self.transport.q: + self.u_dof_stage[ci] = [] + for k in range(self.nStages + 1): + self.u_dof_stage[ci].append(self.transport.u[ci].dof.copy()) + self.substeps = [self.t for i in range(self.nStages)] + + def setFromOptions(self, nOptions): + """ + allow classes to set various numerical parameters + """ + if 'runCFL' in dir(nOptions): + self.runCFL = nOptions.runCFL + flags = ['timeOrder'] + for flag in flags: + if flag in dir(nOptions): + val = getattr(nOptions, flag) + setattr(self, flag, val) + if flag == 'timeOrder': + self.resetOrder(self.timeOrder) + +class Coefficients(proteus.TransportCoefficients.TC_base): + """ + version of Re where element material type id's used in evals + """ + from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2 + from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchten_sd_het + def __init__(self, + nd, + Ksw_types, + vgm_n_types, + vgm_alpha_types, + thetaR_types, + thetaSR_types, + gravity, + density, + beta, + diagonal_conductivity=True, + getSeepageFace=None, + # FOR EDGE BASED EV + STABILIZATION_TYPE=0, + ENTROPY_TYPE=2, # logarithmic + LUMPED_MASS_MATRIX=False, + MONOLITHIC=True, + FCT=False, + forceStrongBoundaryConditions=False, + num_fct_iter=1, + # FOR ENTROPY VISCOSITY + cE=1.0, + uL=0.0, + uR=1.0, + # FOR ARTIFICIAL COMPRESSION + cK=1.0, + # OUTPUT quantDOFs + outputQuantDOFs=False): + variableNames=['pressure_head'] + nc=1 + mass={0:{0:'nonlinear'}} + advection={0:{0:'nonlinear'}} + diffusion={0:{0:{0:'nonlinear'}}} + potential={0:{0:'u'}} + reaction={0:{0:'linear'}} + hamiltonian={} + self.getSeepageFace=getSeepageFace + self.gravity=gravity + self.rho = density + self.beta=beta + self.vgm_n_types = vgm_n_types + self.vgm_alpha_types = vgm_alpha_types + self.thetaR_types = thetaR_types + self.thetaSR_types = thetaSR_types + self.elementMaterialTypes = None + self.exteriorElementBoundaryTypes = None + self.materialTypes_q = None + self.materialTypes_ebq = None + self.materialTypes_ebqe = None + self.nd = nd + self.nMaterialTypes = len(thetaR_types) + self.q = {}; self.ebqe = {}; self.ebq = {}; self.ebq_global={} + #try to allow some flexibility in input of permeability/conductivity tensor + self.diagonal_conductivity = diagonal_conductivity + self.Ksw_types_in = Ksw_types + if self.diagonal_conductivity: + sparseDiffusionTensors = {(0,0):(np.arange(self.nd+1,dtype='i'), + np.arange(self.nd,dtype='i'))} + + assert len(Ksw_types.shape) in [1,2], "if diagonal conductivity true then Ksw_types scalar or vector of diagonal entries" + #allow scalar input Ks + if len(Ksw_types.shape)==1: + self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd),'d') + for I in range(self.nd): + self.Ksw_types[:,I] = Ksw_types + else: + self.Ksw_types = Ksw_types + else: #full + sparseDiffusionTensors = {(0,0):(np.arange(self.nd**2+1,step=self.nd,dtype='i'), + np.array([list(range(self.nd)) for row in range(self.nd)],dtype='i'))} + assert len(Ksw_types.shape) in [1,2], "if full tensor conductivity true then Ksw_types scalar or 'flattened' row-major representation of entries" + if len(Ksw_types.shape)==1: + self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd**2),'d') + for I in range(self.nd): + self.Ksw_types[:,I*self.nd+I] = Ksw_types + else: + assert Ksw_types.shape[1] == self.nd**2 + self.Ksw_types = Ksw_types + # EDGE BASED (AND ENTROPY) VISCOSITY + self.LUMPED_MASS_MATRIX = LUMPED_MASS_MATRIX + self.MONOLITHIC = MONOLITHIC + self.STABILIZATION_TYPE = STABILIZATION_TYPE + self.ENTROPY_TYPE = ENTROPY_TYPE + self.FCT = FCT + self.num_fct_iter=num_fct_iter + self.uL = uL + self.uR = uR + self.cK = cK + self.forceStrongConditions = forceStrongBoundaryConditions + self.cE = cE + self.outputQuantDOFs = outputQuantDOFs + TC_base.__init__(self, + nc, + mass, + advection, + diffusion, + potential, + reaction, + hamiltonian, + variableNames, + sparseDiffusionTensors = sparseDiffusionTensors, + useSparseDiffusion = True) + + def initializeMesh(self,mesh): + from proteus.SubsurfaceTransportCoefficients import BlockHeterogeneousCoefficients + self.elementMaterialTypes,self.exteriorElementBoundaryTypes,self.elementBoundaryTypes = BlockHeterogeneousCoefficients(mesh).initializeMaterialTypes() + #want element boundary material types for evaluating heterogeneity + #not boundary conditions + self.isSeepageFace = np.zeros((mesh.nExteriorElementBoundaries_global),'i') + if self.getSeepageFace != None: + for ebNE in range(mesh.nExteriorElementBoundaries_global): + #mwf missing ebNE-->ebN? + ebN = mesh.exteriorElementBoundariesArray[ebNE] + #print "eb flag",mesh.elementBoundaryMaterialTypes[ebN] + #print self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) + self.isSeepageFace[ebNE] = self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) + #print self.isSeepageFace + def initializeElementQuadrature(self,t,cq): + self.materialTypes_q = self.elementMaterialTypes + self.q_shape = cq[('u',0)].shape +# cq['Ks'] = np.zeros(self.q_shape,'d') +# for k in range(self.q_shape[1]): +# cq['Ks'][:,k] = self.Ksw_types[self.elementMaterialTypes,0] + self.q[('vol_frac',0)] = np.zeros(self.q_shape,'d') + def initializeElementBoundaryQuadrature(self,t,cebq,cebq_global): + self.materialTypes_ebq = np.zeros(cebq[('u',0)].shape[0:2],'i') + self.ebq_shape = cebq[('u',0)].shape + for ebN_local in range(self.ebq_shape[1]): + self.materialTypes_ebq[:,ebN_local] = self.elementMaterialTypes + self.ebq[('vol_frac',0)] = np.zeros(self.ebq_shape,'d') + + def initializeGlobalExteriorElementBoundaryQuadrature(self,t,cebqe): + self.materialTypes_ebqe = self.exteriorElementBoundaryTypes + self.ebqe_shape = cebqe[('u',0)].shape + self.ebqe[('vol_frac',0)] = np.zeros(self.ebqe_shape,'d') + # + def evaluate(self,t,c): + if c[('u',0)].shape == self.q_shape: + materialTypes = self.materialTypes_q + vol_frac = self.q[('vol_frac',0)] + elif c[('u',0)].shape == self.ebqe_shape: + materialTypes = self.materialTypes_ebqe + vol_frac = self.ebqe[('vol_frac',0)] + elif c[('u',0)].shape == self.ebq_shape: + materialTypes = self.materialTypes_ebq + vol_frac = self.ebq[('vol_frac',0)] + else: + assert False, "no materialType found to match c[('u',0)].shape= %s " % c[('u',0)].shape + self.conservativeHeadRichardsMualemVanGenuchten_sd_het(self.sdInfo[(0,0)][0], + self.sdInfo[(0,0)][1], + materialTypes, + self.rho, + self.beta, + self.gravity, + self.vgm_alpha_types, + self.vgm_n_types, + self.thetaR_types, + self.thetaSR_types, + self.Ksw_types, + c[('u',0)], + c[('m',0)], + c[('dm',0,0)], + c[('f',0)], + c[('df',0,0)], + c[('a',0,0)], + c[('da',0,0,0)], + vol_frac) + # print "Picard---------------------------------------------------------------" + # c[('df',0,0)][:] = 0.0 + # c[('da',0,0,0)][:] = 0.0 +# self.conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2(materialTypes, +# self.rho, +# self.beta, +# self.gravity, +# self.vgm_alpha_types, +# self.vgm_n_types, +# self.thetaR_types, +# self.thetaSR_types, +# self.Ksw_types, +# c[('u',0)], +# c[('m',0)], +# c[('dm',0,0)], +# c[('f',0)], +# c[('df',0,0)], +# c[('a',0,0)], +# c[('da',0,0,0)]) + #mwf debug + if (np.isnan(c[('da',0,0,0)]).any() or + np.isnan(c[('a',0,0)]).any() or + np.isnan(c[('df',0,0)]).any() or + np.isnan(c[('f',0)]).any() or + np.isnan(c[('u',0)]).any() or + np.isnan(c[('m',0)]).any() or + np.isnan(c[('dm',0,0)]).any()): + import pdb + pdb.set_trace() + +# #mwf debug +# if c[('u',0)].shape == self.q_shape: +# c[('visPerm',0)]=c[('a',0,0)][:,:,0,0] + +class LevelModel(proteus.Transport.OneLevelTransport): + nCalls=0 + def __init__(self, + uDict, + phiDict, + testSpaceDict, + matType, + dofBoundaryConditionsDict, + dofBoundaryConditionsSetterDict, + coefficients, + elementQuadrature, + elementBoundaryQuadrature, + fluxBoundaryConditionsDict=None, + advectiveFluxBoundaryConditionsSetterDict=None, + diffusiveFluxBoundaryConditionsSetterDictDict=None, + stressTraceBoundaryConditionsSetterDict=None, + stabilization=None, + shockCapturing=None, + conservativeFluxDict=None, + numericalFluxType=None, + TimeIntegrationClass=None, + massLumping=False, + reactionLumping=False, + options=None, + name='defaultName', + reuse_trial_and_test_quadrature=True, + sd = True, + movingDomain=False, + bdyNullSpace=False): + self.bdyNullSpace=bdyNullSpace + # + #set the objects describing the method and boundary conditions + # + self.movingDomain=movingDomain + self.tLast_mesh=None + # + self.name=name + self.sd=sd + self.Hess=False + self.lowmem=True + self.timeTerm=True#allow turning off the time derivative + #self.lowmem=False + self.testIsTrial=True + self.phiTrialIsTrial=True + self.u = uDict + self.ua = {}#analytical solutions + self.phi = phiDict + self.dphi={} + self.matType = matType + #mwf try to reuse test and trial information across components if spaces are the same + self.reuse_test_trial_quadrature = reuse_trial_and_test_quadrature#True#False + if self.reuse_test_trial_quadrature: + for ci in range(1,coefficients.nc): + assert self.u[ci].femSpace.__class__.__name__ == self.u[0].femSpace.__class__.__name__, "to reuse_test_trial_quad all femSpaces must be the same!" + self.u_dof_old = None + ## Simplicial Mesh + self.mesh = self.u[0].femSpace.mesh #assume the same mesh for all components for now + self.testSpace = testSpaceDict + self.dirichletConditions = dofBoundaryConditionsDict + self.dirichletNodeSetList=None #explicit Dirichlet conditions for now, no Dirichlet BC constraints + self.coefficients = coefficients + self.coefficients.initializeMesh(self.mesh) + self.nc = self.coefficients.nc + self.stabilization = stabilization + self.shockCapturing = shockCapturing + self.conservativeFlux = conservativeFluxDict #no velocity post-processing for now + self.fluxBoundaryConditions=fluxBoundaryConditionsDict + self.advectiveFluxBoundaryConditionsSetterDict=advectiveFluxBoundaryConditionsSetterDict + self.diffusiveFluxBoundaryConditionsSetterDictDict = diffusiveFluxBoundaryConditionsSetterDictDict + #determine whether the stabilization term is nonlinear + self.stabilizationIsNonlinear = False + #cek come back + if self.stabilization != None: + for ci in range(self.nc): + if ci in coefficients.mass: + for flag in list(coefficients.mass[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.advection: + for flag in list(coefficients.advection[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.diffusion: + for diffusionDict in list(coefficients.diffusion[ci].values()): + for flag in list(diffusionDict.values()): + if flag != 'constant': + self.stabilizationIsNonlinear=True + if ci in coefficients.potential: + for flag in list(coefficients.potential[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.reaction: + for flag in list(coefficients.reaction[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.hamiltonian: + for flag in list(coefficients.hamiltonian[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + #determine if we need element boundary storage + self.elementBoundaryIntegrals = {} + for ci in range(self.nc): + self.elementBoundaryIntegrals[ci] = ((self.conservativeFlux != None) or + (numericalFluxType != None) or + (self.fluxBoundaryConditions[ci] == 'outFlow') or + (self.fluxBoundaryConditions[ci] == 'mixedFlow') or + (self.fluxBoundaryConditions[ci] == 'setFlow')) + # + #calculate some dimensions + # + self.nSpace_global = self.u[0].femSpace.nSpace_global #assume same space dim for all variables + self.nDOF_trial_element = [u_j.femSpace.max_nDOF_element for u_j in list(self.u.values())] + self.nDOF_phi_trial_element = [phi_k.femSpace.max_nDOF_element for phi_k in list(self.phi.values())] + self.n_phi_ip_element = [phi_k.femSpace.referenceFiniteElement.interpolationConditions.nQuadraturePoints for phi_k in list(self.phi.values())] + self.nDOF_test_element = [femSpace.max_nDOF_element for femSpace in list(self.testSpace.values())] + self.nFreeDOF_global = [dc.nFreeDOF_global for dc in list(self.dirichletConditions.values())] + self.nVDOF_element = sum(self.nDOF_trial_element) + self.nFreeVDOF_global = sum(self.nFreeDOF_global) + # + NonlinearEquation.__init__(self,self.nFreeVDOF_global) + # + #build the quadrature point dictionaries from the input (this + #is just for convenience so that the input doesn't have to be + #complete) + # + elementQuadratureDict={} + elemQuadIsDict = isinstance(elementQuadrature,dict) + if elemQuadIsDict: #set terms manually + for I in self.coefficients.elementIntegralKeys: + if I in elementQuadrature: + elementQuadratureDict[I] = elementQuadrature[I] + else: + elementQuadratureDict[I] = elementQuadrature['default'] + else: + for I in self.coefficients.elementIntegralKeys: + elementQuadratureDict[I] = elementQuadrature + if self.stabilization != None: + for I in self.coefficients.elementIntegralKeys: + if elemQuadIsDict: + if I in elementQuadrature: + elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature[I] + else: + elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature['default'] + else: + elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature + if self.shockCapturing != None: + for ci in self.shockCapturing.components: + if elemQuadIsDict: + if ('numDiff',ci,ci) in elementQuadrature: + elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature[('numDiff',ci,ci)] + else: + elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature['default'] + else: + elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature + if massLumping: + for ci in list(self.coefficients.mass.keys()): + elementQuadratureDict[('m',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + for I in self.coefficients.elementIntegralKeys: + elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + if reactionLumping: + for ci in list(self.coefficients.mass.keys()): + elementQuadratureDict[('r',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + for I in self.coefficients.elementIntegralKeys: + elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + elementBoundaryQuadratureDict={} + if isinstance(elementBoundaryQuadrature,dict): #set terms manually + for I in self.coefficients.elementBoundaryIntegralKeys: + if I in elementBoundaryQuadrature: + elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature[I] + else: + elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature['default'] + else: + for I in self.coefficients.elementBoundaryIntegralKeys: + elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature + # + # find the union of all element quadrature points and + # build a quadrature rule for each integral that has a + # weight at each point in the union + #mwf include tag telling me which indices are which quadrature rule? + (self.elementQuadraturePoints,self.elementQuadratureWeights, + self.elementQuadratureRuleIndeces) = Quadrature.buildUnion(elementQuadratureDict) + self.nQuadraturePoints_element = self.elementQuadraturePoints.shape[0] + self.nQuadraturePoints_global = self.nQuadraturePoints_element*self.mesh.nElements_global + # + #Repeat the same thing for the element boundary quadrature + # + (self.elementBoundaryQuadraturePoints, + self.elementBoundaryQuadratureWeights, + self.elementBoundaryQuadratureRuleIndeces) = Quadrature.buildUnion(elementBoundaryQuadratureDict) + self.nElementBoundaryQuadraturePoints_elementBoundary = self.elementBoundaryQuadraturePoints.shape[0] + self.nElementBoundaryQuadraturePoints_global = (self.mesh.nElements_global* + self.mesh.nElementBoundaries_element* + self.nElementBoundaryQuadraturePoints_elementBoundary) +# if isinstance(self.u[0].femSpace,C0_AffineLinearOnSimplexWithNodalBasis): +# print self.nQuadraturePoints_element +# if self.nSpace_global == 3: +# assert(self.nQuadraturePoints_element == 5) +# elif self.nSpace_global == 2: +# assert(self.nQuadraturePoints_element == 6) +# elif self.nSpace_global == 1: +# assert(self.nQuadraturePoints_element == 3) +# +# print self.nElementBoundaryQuadraturePoints_elementBoundary +# if self.nSpace_global == 3: +# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) +# elif self.nSpace_global == 2: +# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) +# elif self.nSpace_global == 1: +# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 1) + + # + #storage dictionaries + self.scalars_element = set() + # + #simplified allocations for test==trial and also check if space is mixed or not + # + self.q={} + self.ebq={} + self.ebq_global={} + self.ebqe={} + self.phi_ip={} + self.edge_based_cfl = np.zeros(self.u[0].dof.shape)+100 + #mesh + #self.q['x'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,3),'d') + self.q[('dV_u', 0)] = (old_div(1.0, self.mesh.nElements_global)) * np.ones((self.mesh.nElements_global, self.nQuadraturePoints_element), 'd') + self.ebqe['x'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,3),'d') + self.q[('u',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') + self.q[('grad(u)',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') + self.q['velocity'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') + self.q[('m',0)] = self.q[('u',0)].copy() + self.q[('mt',0)] = self.q[('u',0)].copy() + self.q[('m_last',0)] = self.q[('u',0)].copy() + self.q[('m_tmp',0)] = self.q[('u',0)].copy() + self.q[('cfl',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') + self.q[('numDiff',0,0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') + self.ebqe[('u',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.ebqe[('grad(u)',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') + self.ebqe['velocity'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') + self.ebqe[('advectiveFlux_bc_flag',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'i') + self.ebqe[('advectiveFlux_bc',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.ebqe[('advectiveFlux',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.ebqe[('penalty')] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.points_elementBoundaryQuadrature= set() + self.scalars_elementBoundaryQuadrature= set([('u',ci) for ci in range(self.nc)]) + self.vectors_elementBoundaryQuadrature= set() + self.tensors_elementBoundaryQuadrature= set() + self.inflowBoundaryBC = {} + self.inflowBoundaryBC_values = {} + self.inflowFlux = {} + for cj in range(self.nc): + self.inflowBoundaryBC[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,),'i') + self.inflowBoundaryBC_values[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nDOF_trial_element[cj]),'d') + self.inflowFlux[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.internalNodes = set(range(self.mesh.nNodes_global)) + #identify the internal nodes this is ought to be in mesh + ##\todo move this to mesh + for ebNE in range(self.mesh.nExteriorElementBoundaries_global): + ebN = self.mesh.exteriorElementBoundariesArray[ebNE] + eN_global = self.mesh.elementBoundaryElementsArray[ebN,0] + ebN_element = self.mesh.elementBoundaryLocalElementBoundariesArray[ebN,0] + for i in range(self.mesh.nNodes_element): + if i != ebN_element: + I = self.mesh.elementNodesArray[eN_global,i] + self.internalNodes -= set([I]) + self.nNodes_internal = len(self.internalNodes) + self.internalNodesArray=np.zeros((self.nNodes_internal,),'i') + for nI,n in enumerate(self.internalNodes): + self.internalNodesArray[nI]=n + # + del self.internalNodes + self.internalNodes = None + logEvent("Updating local to global mappings",2) + self.updateLocal2Global() + logEvent("Building time integration object",2) + logEvent(memory("inflowBC, internalNodes,updateLocal2Global","OneLevelTransport"),level=4) + #mwf for interpolating subgrid error for gradients etc + if self.stabilization and self.stabilization.usesGradientStabilization: + self.timeIntegration = TimeIntegrationClass(self,integrateInterpolationPoints=True) + else: + self.timeIntegration = TimeIntegrationClass(self) + + if options != None: + self.timeIntegration.setFromOptions(options) + logEvent(memory("TimeIntegration","OneLevelTransport"),level=4) + logEvent("Calculating numerical quadrature formulas",2) + self.calculateQuadrature() + #lay out components/equations contiguously for now + self.offset = [0] + for ci in range(1,self.nc): + self.offset += [self.offset[ci-1]+self.nFreeDOF_global[ci-1]] + self.stride = [1 for ci in range(self.nc)] + #use contiguous layout of components for parallel, requires weak DBC's + # mql. Some ASSERTS to restrict the combination of the methods + if self.coefficients.STABILIZATION_TYPE > 0: + pass + #assert self.timeIntegration.isSSP == True, "If STABILIZATION_TYPE>0, use RKEV timeIntegration within VOF model" + #cond = 'levelNonlinearSolver' in dir(options) and (options.levelNonlinearSolver == + # ExplicitLumpedMassMatrixForRichards or options.levelNonlinearSolver == ExplicitConsistentMassMatrixForRichards) + #assert cond, "If STABILIZATION_TYPE>0, use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards or ExplicitConsistentMassMatrixForRichards" + try: + if 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards: + assert self.coefficients.LUMPED_MASS_MATRIX, "If levelNonlinearSolver=ExplicitLumpedMassMatrix, use LUMPED_MASS_MATRIX=True" + except: + pass + if self.coefficients.LUMPED_MASS_MATRIX == True: + cond = self.coefficients.STABILIZATION_TYPE == 2 + assert cond, "Use lumped mass matrix just with: STABILIZATION_TYPE=2 (smoothness based stab.)" + cond = 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards + assert cond, "Use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards when the mass matrix is lumped" + if self.coefficients.FCT == True: + cond = self.coefficients.STABILIZATION_TYPE > 0, "Use FCT just with STABILIZATION_TYPE>0; i.e., edge based stabilization" + # END OF ASSERTS + + # cek adding empty data member for low order numerical viscosity structures here for now + self.ML = None # lumped mass matrix + self.MC_global = None # consistent mass matrix + self.cterm_global = None + self.cterm_transpose_global = None + # dL_global and dC_global are not the full matrices but just the CSR arrays containing the non zero entries + self.residualComputed=False #TMP + self.dLow= None + self.fluxMatrix = None + self.uDotLow = None + self.uLow = None + self.dt_times_dC_minus_dL = None + self.min_s_bc = None + self.max_s_bc = None + # Aux quantity at DOFs to be filled by optimized code (MQL) + self.quantDOFs = np.zeros(self.u[0].dof.shape, 'd') + self.sLow = np.zeros(self.u[0].dof.shape, 'd') + self.sHigh = np.zeros(self.u[0].dof.shape, 'd') + self.sn = np.zeros(self.u[0].dof.shape, 'd') + comm = Comm.get() + self.comm=comm + if comm.size() > 1: + assert numericalFluxType != None and numericalFluxType.useWeakDirichletConditions,"You must use a numerical flux to apply weak boundary conditions for parallel runs" + self.offset = [0] + for ci in range(1,self.nc): + self.offset += [ci] + self.stride = [self.nc for ci in range(self.nc)] + # + logEvent(memory("stride+offset","OneLevelTransport"),level=4) + if numericalFluxType != None: + if options is None or options.periodicDirichletConditions is None: + self.numericalFlux = numericalFluxType(self, + dofBoundaryConditionsSetterDict, + advectiveFluxBoundaryConditionsSetterDict, + diffusiveFluxBoundaryConditionsSetterDictDict) + else: + self.numericalFlux = numericalFluxType(self, + dofBoundaryConditionsSetterDict, + advectiveFluxBoundaryConditionsSetterDict, + diffusiveFluxBoundaryConditionsSetterDictDict, + options.periodicDirichletConditions) + else: + self.numericalFlux = None + #set penalty terms + #cek todo move into numerical flux initialization + if 'penalty' in self.ebq_global: + for ebN in range(self.mesh.nElementBoundaries_global): + for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): + self.ebq_global['penalty'][ebN,k] = old_div(self.numericalFlux.penalty_constant,(self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power)) + #penalty term + #cek move to Numerical flux initialization + if 'penalty' in self.ebqe: + for ebNE in range(self.mesh.nExteriorElementBoundaries_global): + ebN = self.mesh.exteriorElementBoundariesArray[ebNE] + for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): + self.ebqe['penalty'][ebNE,k] = old_div(self.numericalFlux.penalty_constant,self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power) + logEvent(memory("numericalFlux","OneLevelTransport"),level=4) + self.elementEffectiveDiametersArray = self.mesh.elementInnerDiametersArray + #use post processing tools to get conservative fluxes, None by default + from proteus import PostProcessingTools + self.velocityPostProcessor = PostProcessingTools.VelocityPostProcessingChooser(self) + logEvent(memory("velocity postprocessor","OneLevelTransport"),level=4) + #helper for writing out data storage + from proteus import Archiver + self.elementQuadratureDictionaryWriter = Archiver.XdmfWriter() + self.elementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() + self.exteriorElementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() + #TODO get rid of this + for ci,fbcObject in list(self.fluxBoundaryConditionsObjectsDict.items()): + self.ebqe[('advectiveFlux_bc_flag',ci)] = np.zeros(self.ebqe[('advectiveFlux_bc',ci)].shape,'i') + for t,g in list(fbcObject.advectiveFluxBoundaryConditionsDict.items()): + if ci in self.coefficients.advection: + self.ebqe[('advectiveFlux_bc',ci)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) + self.ebqe[('advectiveFlux_bc_flag',ci)][t[0],t[1]] = 1 + + if hasattr(self.numericalFlux,'setDirichletValues'): + self.numericalFlux.setDirichletValues(self.ebqe) + if not hasattr(self.numericalFlux,'isDOFBoundary'): + self.numericalFlux.isDOFBoundary = {0:np.zeros(self.ebqe[('u',0)].shape,'i')} + if not hasattr(self.numericalFlux,'ebqe'): + self.numericalFlux.ebqe = {('u',0):np.zeros(self.ebqe[('u',0)].shape,'d')} + #TODO how to handle redistancing calls for calculateCoefficients,calculateElementResidual etc + self.globalResidualDummy = None + compKernelFlag=0 + self.delta_x_ij=None + self.richards = cRichards_base(self.nSpace_global, + self.nQuadraturePoints_element, + self.u[0].femSpace.elementMaps.localFunctionSpace.dim, + self.u[0].femSpace.referenceFiniteElement.localFunctionSpace.dim, + self.testSpace[0].referenceFiniteElement.localFunctionSpace.dim, + self.nElementBoundaryQuadraturePoints_elementBoundary, + compKernelFlag) + if self.movingDomain: + self.MOVING_DOMAIN=1.0 + else: + self.MOVING_DOMAIN=0.0 + #cek hack + self.movingDomain=False + self.MOVING_DOMAIN=0.0 + if self.mesh.nodeVelocityArray is None: + self.mesh.nodeVelocityArray = np.zeros(self.mesh.nodeArray.shape,'d') + self.forceStrongConditions=self.coefficients.forceStrongConditions + self.dirichletConditionsForceDOF = {} + if self.forceStrongConditions: + for cj in range(self.nc): + self.dirichletConditionsForceDOF[cj] = DOFBoundaryConditions(self.u[cj].femSpace,dofBoundaryConditionsSetterDict[cj],weakDirichletConditions=False) + def FCTStep(self): + import pdb + rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() + limited_solution = np.zeros((len(rowptr) - 1),'d') + #self.u_free_dof_stage_0_l = np.zeros((len(rowptr) - 1),'d') + #self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage], # soln + #fromFreeToGlobal=0 + #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + # self.offset[0], + # self.stride[0], + # self.dirichletConditions[0].global2freeGlobal_global_dofs, + # self.dirichletConditions[0].global2freeGlobal_free_dofs, + # self.u_free_dof_stage_0_l, + # self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage]) + argsDict = cArgumentsDict.ArgumentsDict() + argsDict["bc_mask"] = self.bc_mask + argsDict["NNZ"] = self.nnz + argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs + argsDict["dt"] = self.timeIntegration.dt + argsDict["lumped_mass_matrix"] = self.ML + argsDict["soln"] = self.sn + argsDict["pn"] = self.u[0].dof + argsDict["solH"] = self.sHigh + argsDict["uLow"] = self.sLow + argsDict["uDotLow"] = self.uDotLow + argsDict["limited_solution"] = limited_solution + argsDict["csrRowIndeces_DofLoops"] = rowptr + argsDict["csrColumnOffsets_DofLoops"] = colind + argsDict["MassMatrix"] = MassMatrix + argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL + argsDict["min_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0]) #cek hack just set from physical bounds + argsDict["max_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0] + self.coefficients.thetaSR_types[0]) #cek hack + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["MONOLITHIC"] =0#cek hack self.coefficients.MONOLITHIC + #pdb.set_trace() + self.richards.FCTStep(argsDict) + + # self.nnz, # number of non zero entries + # len(rowptr) - 1, # number of DOFs + # self.timeIntegration.dt, + # self.ML, # Lumped mass matrix + # self.sn, + # self.u_dof_old, + # self.sHigh, # high order solution + # self.sLow, + # limited_solution, + # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) + # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) + # MassMatrix, + # self.dt_times_dC_minus_dL, + # self.min_s_bc, + # self.max_s_bc, + # self.coefficients.LUMPED_MASS_MATRIX, + # self.coefficients.MONOLITHIC) + old_dof = self.u[0].dof.copy() + self.invert(limited_solution, self.u[0].dof) + self.timeIntegration.u[:] = self.u[0].dof + #fromFreeToGlobal=1 #direction copying + #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + # self.offset[0], + # self.stride[0], + # self.dirichletConditions[0].global2freeGlobal_global_dofs, + # self.dirichletConditions[0].global2freeGlobal_free_dofs, + # self.u[0].dof, + # limited_solution) + def kth_FCT_step(self): + #import pdb + #pdb.set_trace() + rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() + limitedFlux = np.zeros(self.nnz) + limited_solution = np.zeros((len(rowptr) - 1),'d') + #limited_solution[:] = self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage] + fromFreeToGlobal=0 #direction copying + cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + self.offset[0], + self.stride[0], + self.dirichletConditions[0].global2freeGlobal_global_dofs, + self.dirichletConditions[0].global2freeGlobal_free_dofs, + limited_solution, + self.timeintegration.u_dof_stage[0][self.timeIntegration.lstage]) + + self.richards.kth_FCT_step( + self.timeIntegration.dt, + self.coefficients.num_fct_iter, + self.nnz, # number of non zero entries + len(rowptr) - 1, # number of DOFs + MassMatrix, + self.ML, # Lumped mass matrix + self.u_dof_old, + limited_solution, + self.uDotLow, + self.uLow, + self.dLow, + self.fluxMatrix, + limitedFlux, + rowptr, + colind) + + self.timeIntegration.u[:] = limited_solution + #self.u[0].dof[:] = limited_solution + fromFreeToGlobal=1 #direction copying + cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + self.offset[0], + self.stride[0], + self.dirichletConditions[0].global2freeGlobal_global_dofs, + self.dirichletConditions[0].global2freeGlobal_free_dofs, + self.u[0].dof, + limited_solution) + def calculateCoefficients(self): + pass + def calculateElementResidual(self): + if self.globalResidualDummy != None: + self.getResidual(self.u[0].dof,self.globalResidualDummy) + def getResidual(self,u,r): + import pdb + import copy + """ + Calculate the element residuals and add in to the global residual + """ + cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, + self.jacobian) + if self.u_dof_old is None: + # Pass initial condition to u_dof_old + self.u_dof_old = np.copy(self.u[0].dof) + rowptr, colind, nzval = self.jacobian.getCSRrepresentation() + nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix + r.fill(0.0) + ######################## + ### COMPUTE C MATRIX ### + ######################## + if self.cterm_global is None: + # since we only need cterm_global to persist, we can drop the other self.'s + self.cterm = {} + self.cterm_a = {} + self.cterm_global = {} + self.cterm_transpose = {} + self.cterm_a_transpose = {} + self.cterm_global_transpose = {} + rowptr, colind, nzval = self.jacobian.getCSRrepresentation() + nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix + di = self.q[('grad(u)', 0)].copy() # direction of derivative + # JACOBIANS (FOR ELEMENT TRANSFORMATION) + self.q[('J')] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nSpace_global, + self.nSpace_global), + 'd') + self.q[('inverse(J)')] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nSpace_global, + self.nSpace_global), + 'd') + self.q[('det(J)')] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element), + 'd') + self.u[0].femSpace.elementMaps.getJacobianValues(self.elementQuadraturePoints, + self.q['J'], + self.q['inverse(J)'], + self.q['det(J)']) + self.q['abs(det(J))'] = np.abs(self.q['det(J)']) + # SHAPE FUNCTIONS + self.q[('w', 0)] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nDOF_test_element[0]), + 'd') + self.q[('w*dV_m', 0)] = self.q[('w', 0)].copy() + self.u[0].femSpace.getBasisValues(self.elementQuadraturePoints, self.q[('w', 0)]) + cfemIntegrals.calculateWeightedShape(self.elementQuadratureWeights[('u', 0)], + self.q['abs(det(J))'], + self.q[('w', 0)], + self.q[('w*dV_m', 0)]) + # GRADIENT OF TEST FUNCTIONS + self.q[('grad(w)', 0)] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nDOF_test_element[0], + self.nSpace_global), + 'd') + self.u[0].femSpace.getBasisGradientValues(self.elementQuadraturePoints, + self.q['inverse(J)'], + self.q[('grad(w)', 0)]) + self.q[('grad(w)*dV_f', 0)] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nDOF_test_element[0], + self.nSpace_global), + 'd') + cfemIntegrals.calculateWeightedShapeGradients(self.elementQuadratureWeights[('u', 0)], + self.q['abs(det(J))'], + self.q[('grad(w)', 0)], + self.q[('grad(w)*dV_f', 0)]) + ########################## + ### LUMPED MASS MATRIX ### + ########################## + # assume a linear mass term + dm = np.ones(self.q[('u', 0)].shape, 'd') + elementMassMatrix = np.zeros((self.mesh.nElements_global, + self.nDOF_test_element[0], + self.nDOF_trial_element[0]), 'd') + cfemIntegrals.updateMassJacobian_weak_lowmem(dm, + self.q[('w', 0)], + self.q[('w*dV_m', 0)], + elementMassMatrix) + self.MC_a = nzval.copy() + self.MC_global = SparseMat(self.nFreeDOF_global[0], + self.nFreeDOF_global[0], + nnz, + self.MC_a, + colind, + rowptr) + cfemIntegrals.zeroJacobian_CSR(self.nnz, self.MC_global) + cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.csrRowIndeces[(0, 0)], + self.csrColumnOffsets[(0, 0)], + elementMassMatrix, + self.MC_global) + self.ML = np.zeros((self.nFreeDOF_global[0],), 'd') + for i in range(self.nFreeDOF_global[0]): + self.ML[i] = self.MC_a[rowptr[i]:rowptr[i + 1]].sum() + np.testing.assert_almost_equal(self.ML.sum(), + self.mesh.volume, + err_msg="Trace of lumped mass matrix should be the domain volume", verbose=True) + for d in range(self.nSpace_global): # spatial dimensions + # C matrices + self.cterm[d] = np.zeros((self.mesh.nElements_global, + self.nDOF_test_element[0], + self.nDOF_trial_element[0]), 'd') + self.cterm_a[d] = nzval.copy() + #self.cterm_a[d] = np.zeros(nzval.size) + self.cterm_global[d] = SparseMat(self.nFreeDOF_global[0], + self.nFreeDOF_global[0], + nnz, + self.cterm_a[d], + colind, + rowptr) + cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global[d]) + di[:] = 0.0 + di[..., d] = 1.0 + cfemIntegrals.updateHamiltonianJacobian_weak_lowmem(di, + self.q[('grad(w)*dV_f', 0)], + self.q[('w', 0)], + self.cterm[d]) # int[(di*grad(wj))*wi*dV] + cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.csrRowIndeces[(0, 0)], + self.csrColumnOffsets[(0, 0)], + self.cterm[d], + self.cterm_global[d]) + # C Transpose matrices + self.cterm_transpose[d] = np.zeros((self.mesh.nElements_global, + self.nDOF_test_element[0], + self.nDOF_trial_element[0]), 'd') + self.cterm_a_transpose[d] = nzval.copy() + self.cterm_global_transpose[d] = SparseMat(self.nFreeDOF_global[0], + self.nFreeDOF_global[0], + nnz, + self.cterm_a_transpose[d], + colind, + rowptr) + cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global_transpose[d]) + di[:] = 0.0 + di[..., d] = -1.0 + cfemIntegrals.updateAdvectionJacobian_weak_lowmem(di, + self.q[('w', 0)], + self.q[('grad(w)*dV_f', 0)], + self.cterm_transpose[d]) # -int[(-di*grad(wi))*wj*dV] + cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.csrRowIndeces[(0, 0)], + self.csrColumnOffsets[(0, 0)], + self.cterm_transpose[d], + self.cterm_global_transpose[d]) + + rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() + else: + Cy = np.zeros(Cx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() + else: + Cz = np.zeros(Cx.shape, 'd') + rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() + else: + CTy = np.zeros(CTx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() + else: + CTz = np.zeros(CTx.shape, 'd') + + # This is dummy. I just care about the csr structure of the sparse matrix + self.dLow = np.zeros(Cx.shape, 'd') + self.fluxMatrix = np.zeros(Cx.shape, 'd') + self.dt_times_dC_minus_dL = np.zeros(Cx.shape, 'd') + nFree = len(rowptr)-1 + self.min_s_bc = np.zeros(nFree, 'd') + 1E10 + self.max_s_bc = np.zeros(nFree, 'd') - 1E10 + self.uDotLow = np.zeros(nFree, 'd') + self.uLow = np.zeros(nFree, 'd') + # + # cek end computationa of cterm_global + # + # cek showing mquezada an example of using cterm_global sparse matrix + # calculation y = c*x where x==1 + # direction=0 + #rowptr, colind, c = self.cterm_global[direction].getCSRrepresentation() + #y = np.zeros((self.nFreeDOF_global[0],),'d') + #x = np.ones((self.nFreeDOF_global[0],),'d') + # ij=0 + # for i in range(self.nFreeDOF_global[0]): + # for offset in range(rowptr[i],rowptr[i+1]): + # j = colind[offset] + # y[i] += c[ij]*x[j] + # ij+=1 + #Load the unknowns into the finite element dof + self.timeIntegration.calculateCoefs() + self.timeIntegration.calculateU(u) + self.setUnknowns(self.timeIntegration.u) + #cek can put in logic to skip of BC's don't depend on t or u + #Dirichlet boundary conditions + self.numericalFlux.setDirichletValues(self.ebqe) + #flux boundary conditions + #cek hack, just using advective flux for flux BC for now + for t,g in list(self.fluxBoundaryConditionsObjectsDict[0].advectiveFluxBoundaryConditionsDict.items()): + self.ebqe[('advectiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) + self.ebqe[('advectiveFlux_bc_flag',0)][t[0],t[1]] = 1 + # for t,g in self.fluxBoundaryConditionsObjectsDict[0].diffusiveFluxBoundaryConditionsDict.iteritems(): + # self.ebqe[('diffusiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) + # self.ebqe[('diffusiveFlux_bc_flag',0)][t[0],t[1]] = 1 + #self.shockCapturing.lag=True + if self.forceStrongConditions: + self.bc_mask = np.ones_like(self.u[0].dof) + for cj in range(len(self.dirichletConditionsForceDOF)): + for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): + self.u[cj].dof[dofN] = g(self.dirichletConditionsForceDOF[cj].DOFBoundaryPointDict[dofN],self.timeIntegration.t) + self.u_dof_old[dofN] = self.u[cj].dof[dofN] + self.bc_mask[dofN] = 0.0 + degree_polynomial = 1 + try: + degree_polynomial = self.u[0].femSpace.order + except: + pass + + argsDict = cArgumentsDict.ArgumentsDict() + if self.forceStrongConditions: + argsDict["bc_mask"] = self.bc_mask + argsDict["dt"] = self.timeIntegration.dt + argsDict["Theta"] = 1.0 + argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi + argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi + argsDict["mesh_dof"] = self.mesh.nodeArray + argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray + argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN + argsDict["mesh_l2g"] = self.mesh.elementNodesArray + argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] + argsDict["u_trial_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi + argsDict["u_test_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi + argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace + argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace + argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] + argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals + argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians + argsDict["nElements_global"] = self.mesh.nElements_global + argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] + argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, + argsDict["isSeepageFace"] = self.coefficients.isSeepageFace + argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] + argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] + argsDict["rho"] = self.coefficients.rho + argsDict["beta"] = self.coefficients.beta + argsDict["gravity"] = self.coefficients.gravity + argsDict["alpha"] = self.coefficients.vgm_alpha_types + argsDict["n"] = self.coefficients.vgm_n_types + argsDict["thetaR"] = self.coefficients.thetaR_types + argsDict["thetaSR"] = self.coefficients.thetaSR_types + argsDict["KWs"] = self.coefficients.Ksw_types + argsDict["useMetrics"] = 0.0 + argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf + argsDict["lag_shockCapturing"] = 0 + argsDict["shockCapturingDiffusion"] = 0.0 + argsDict["sc_uref"] = 0.0 + argsDict["sc_alpha"] = 0.0 + argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g + argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] + argsDict["elementDiameter"] = self.mesh.elementDiametersArray + argsDict["degree_polynomial"] = degree_polynomial + argsDict["u_dof"] = self.u[0].dof + argsDict["u_dof_old"] = self.u_dof_old + argsDict["velocity"] = self.q['velocity'] + argsDict["q_m"] = self.timeIntegration.m_tmp[0] + argsDict["q_u"] = self.q[('u',0)] + argsDict["q_dV"] = self.q[('dV_u',0)] + argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] + argsDict["cfl"] = self.q[('cfl',0)] + argsDict["q_numDiff_u"] = self.q[('cfl',0)] + argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] + argsDict["offset_u"] = self.offset[0] + argsDict["stride_u"] = self.stride[0] + argsDict["globalResidual"] = r + argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global + argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray + argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray + argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray + argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] + argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] + argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] + argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] + argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] + argsDict["ebqe_phi"] = self.ebqe[('u',0)] + argsDict["epsFact"] = 0.0 + argsDict["ebqe_u"] = self.ebqe[('u',0)] + argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] + argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE + # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION + argsDict["cE"] = self.coefficients.cE + argsDict["cK"] = self.coefficients.cK + # PARAMETERS FOR LOG BASED ENTROPY FUNCTION + argsDict["uL"] = self.coefficients.uL + argsDict["uR"] = self.coefficients.uR + # PARAMETERS FOR EDGE VISCOSITY + argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs + argsDict["NNZ"] = self.nnz + argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern + argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) + argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) + argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms + argsDict["globalJacobian"] = self.jacobian.getCSRrepresentation()[2] + # C matrices + argsDict["Cx"] = Cx + argsDict["Cy"] = Cy + argsDict["Cz"] = Cz + argsDict["CTx"] = CTx + argsDict["CTy"] = CTy + argsDict["CTz"] = CTz + argsDict["ML"] = self.ML + argsDict["delta_x_ij"] = self.delta_x_ij + # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE + argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE + # FLUX CORRECTED TRANSPORT + argsDict["dLow"] = self.dLow + argsDict["fluxMatrix"] = self.fluxMatrix + argsDict["uDotLow"] = self.uDotLow + argsDict["uLow"] = self.uLow + argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL + argsDict["min_s_bc"] = self.min_s_bc + argsDict["max_s_bc"] = self.max_s_bc + argsDict["quantDOFs"] = self.quantDOFs + argsDict["sLow"] = self.sLow + argsDict["sn"] = self.sn + if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG + self.calculateResidual = self.richards.calculateResidual + self.calculateJacobian = self.richards.calculateJacobian + else: + self.calculateResidual = self.richards.calculateResidual_entropy_viscosity + self.calculateJacobian = self.richards.calculateMassMatrix + if self.delta_x_ij is None: + self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') + self.calculateResidual(argsDict) + #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] + #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf + #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] + #self.timeIntegration.calculateElementCoefficients(self.q) + if self.forceStrongConditions:# + for cj in range(len(self.dirichletConditionsForceDOF)):# + for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): + r[self.offset[cj]+self.stride[cj]*dofN] = 0 + if self.stabilization: + self.stabilization.accumulateSubgridMassHistory(self.q) + logEvent("Global residual",level=9,data=r) + self.nonlinear_function_evaluations += 1 + if self.globalResidualDummy is None: + self.globalResidualDummy = np.zeros(r.shape,'d') + + def invert(self,u,r): + #u=s + #r=p + import pdb + import copy + """ + Calculate the element residuals and add in to the global residual + """ + self.sHigh[:] = u + rowptr, colind, nzval = self.jacobian.getCSRrepresentation() + nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix + r.fill(0.0) + rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() + else: + Cy = np.zeros(Cx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() + else: + Cz = np.zeros(Cx.shape, 'd') + rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() + else: + CTy = np.zeros(CTx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() + else: + CTz = np.zeros(CTx.shape, 'd') + + # This is dummy. I just care about the csr structure of the sparse matrix + nFree = len(rowptr)-1 + degree_polynomial = 1 + try: + degree_polynomial = self.u[0].femSpace.order + except: + pass + if self.delta_x_ij is None: + self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') + argsDict = cArgumentsDict.ArgumentsDict() + argsDict["dt"] = self.timeIntegration.dt + argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi + argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi + argsDict["mesh_dof"] = self.mesh.nodeArray + argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray + argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN + argsDict["mesh_l2g"] = self.mesh.elementNodesArray + argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] + argsDict["u_trial_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi + argsDict["u_test_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi + argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace + argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace + argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] + argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals + argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians + argsDict["nElements_global"] = self.mesh.nElements_global + argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] + argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, + argsDict["isSeepageFace"] = self.coefficients.isSeepageFace + argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] + argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] + argsDict["rho"] = self.coefficients.rho + argsDict["beta"] = self.coefficients.beta + argsDict["gravity"] = self.coefficients.gravity + argsDict["alpha"] = self.coefficients.vgm_alpha_types + argsDict["n"] = self.coefficients.vgm_n_types + argsDict["thetaR"] = self.coefficients.thetaR_types + argsDict["thetaSR"] = self.coefficients.thetaSR_types + argsDict["KWs"] = self.coefficients.Ksw_types + argsDict["useMetrics"] = 0.0 + argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf + argsDict["lag_shockCapturing"] = 0 + argsDict["shockCapturingDiffusion"] = 0.0 + argsDict["sc_uref"] = 0.0 + argsDict["sc_alpha"] = 0.0 + argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g + argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] + argsDict["elementDiameter"] = self.mesh.elementDiametersArray + argsDict["degree_polynomial"] = degree_polynomial + argsDict["u_dof"] = u#self.u[0].dof + argsDict["u_dof_old"] = self.u[0].dof + argsDict["velocity"] = self.q['velocity'] + argsDict["q_m"] = self.timeIntegration.m_tmp[0] + argsDict["q_u"] = self.q[('u',0)] + argsDict["q_dV"] = self.q[('dV_u',0)] + argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] + argsDict["cfl"] = self.q[('cfl',0)] + argsDict["q_numDiff_u"] = self.q[('cfl',0)] + argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] + argsDict["offset_u"] = self.offset[0] + argsDict["stride_u"] = self.stride[0] + argsDict["globalResidual"] = r + argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global + argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray + argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray + argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray + argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] + argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] + argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] + argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] + argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] + argsDict["ebqe_phi"] = self.ebqe[('u',0)] + argsDict["epsFact"] = 0.0 + argsDict["ebqe_u"] = self.ebqe[('u',0)] + argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] + argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE + # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION + argsDict["cE"] = self.coefficients.cE + argsDict["cK"] = self.coefficients.cK + # PARAMETERS FOR LOG BASED ENTROPY FUNCTION + argsDict["uL"] = self.coefficients.uL + argsDict["uR"] = self.coefficients.uR + # PARAMETERS FOR EDGE VISCOSITY + argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs + argsDict["NNZ"] = self.nnz + argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern + argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) + argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) + argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms + # C matrices + argsDict["Cx"] = Cx + argsDict["Cy"] = Cy + argsDict["Cz"] = Cz + argsDict["CTx"] = CTx + argsDict["CTy"] = CTy + argsDict["CTz"] = CTz + argsDict["ML"] = self.ML + argsDict["delta_x_ij"] = self.delta_x_ij + # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE + argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE + # FLUX CORRECTED TRANSPORT + argsDict["dLow"] = self.dLow + argsDict["fluxMatrix"] = self.fluxMatrix + argsDict["uDotLow"] = self.uDotLow + argsDict["uLow"] = self.uLow + argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL + argsDict["min_s_bc"] = self.min_s_bc + argsDict["max_s_bc"] = self.max_s_bc + argsDict["quantDOFs"] = self.quantDOFs + argsDict["sLow"] = self.sLow + argsDict["sn"] = self.sn + self.richards.invert(argsDict) + # self.timeIntegration.dt, + # self.u[0].femSpace.elementMaps.psi, + # self.u[0].femSpace.elementMaps.grad_psi, + # self.mesh.nodeArray, + # self.mesh.nodeVelocityArray, + # self.MOVING_DOMAIN, + # self.mesh.elementNodesArray, + # self.elementQuadratureWeights[('u',0)], + # self.u[0].femSpace.psi, + # self.u[0].femSpace.grad_psi, + # self.u[0].femSpace.psi, + # self.u[0].femSpace.grad_psi, + # #element boundary + # self.u[0].femSpace.elementMaps.psi_trace, + # self.u[0].femSpace.elementMaps.grad_psi_trace, + # self.elementBoundaryQuadratureWeights[('u',0)], + # self.u[0].femSpace.psi_trace, + # self.u[0].femSpace.grad_psi_trace, + # self.u[0].femSpace.psi_trace, + # self.u[0].femSpace.grad_psi_trace, + # self.u[0].femSpace.elementMaps.boundaryNormals, + # self.u[0].femSpace.elementMaps.boundaryJacobians, + # #physics + # self.mesh.nElements_global, + # self.ebqe['penalty'],#double* ebqe_penalty_ext, + # self.mesh.elementMaterialTypes,#int* elementMaterialTypes, + # self.coefficients.isSeepageFace, + # self.coefficients.sdInfo[(0,0)][0],#int* a_rowptr, + # self.coefficients.sdInfo[(0,0)][1],#int* a_colind, + # self.coefficients.rho,#double rho, + # self.coefficients.beta,#double beta, + # self.coefficients.gravity,#double* gravity, + # self.coefficients.vgm_alpha_types,#double* alpha, + # self.coefficients.vgm_n_types,#double* n, + # self.coefficients.thetaR_types,#double* thetaR, + # self.coefficients.thetaSR_types,#double* thetaSR, + # self.coefficients.Ksw_types,#double* KWs, + # False,#self.coefficients.useMetrics, + # self.timeIntegration.alpha_bdf, + # 0,#self.shockCapturing.lag, + # 0.0,#cek hack self.shockCapturing.shockCapturingFactor, + # 0.0,#self.coefficients.sc_uref, + # 0.0,#self.coefficients.sc_beta, + # self.u[0].femSpace.dofMap.l2g, + # self.l2g[0]['freeGlobal'], + # self.mesh.elementDiametersArray, + # degree_polynomial, + # self.sHigh, + # self.u_dof_old, + # self.q['velocity'],#self.coefficients.q_v, + # self.timeIntegration.m_tmp[0], + # self.q[('u',0)], + # self.timeIntegration.beta_bdf[0], + # self.q[('cfl',0)], + # self.edge_based_cfl, + # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff[0], + # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff_last[0], + # self.offset[0],self.stride[0], + # r, + # self.mesh.nExteriorElementBoundaries_global, + # self.mesh.exteriorElementBoundariesArray, + # self.mesh.elementBoundaryElementsArray, + # self.mesh.elementBoundaryLocalElementBoundariesArray, + # self.ebqe['velocity'],#self.coefficients.ebqe_v, + # self.numericalFlux.isDOFBoundary[0], + # self.numericalFlux.ebqe[('u',0)], + # self.ebqe[('advectiveFlux_bc_flag',0)], + # self.ebqe[('advectiveFlux_bc',0)], + # self.ebqe[('u',0)],#cek hack self.coefficients.ebqe_phi, + # 0.0,#cek hack self.coefficients.epsFact, + # self.ebqe[('u',0)], + # self.ebqe[('advectiveFlux',0)], + # # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION + # self.coefficients.cE, + # self.coefficients.cK, + # # PARAMETERS FOR LOG BASED ENTROPY FUNCTION + # self.coefficients.uL, + # self.coefficients.uR, + # # PARAMETERS FOR EDGE VISCOSITY + # len(rowptr) - 1, # num of DOFs + # len(Cx), # num of non-zero entries in the sparsity pattern + # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) + # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) + # self.csrRowIndeces[(0, 0)], # row indices (convenient for element loops) + # self.csrColumnOffsets[(0, 0)], # column indices (convenient for element loops) + # self.csrColumnOffsets_eb[(0, 0)], # indices for boundary terms + # # C matrices + # Cx, + # Cy, + # Cz, + # CTx, + # CTy, + # CTz, + # self.ML, + # self.delta_x_ij, + # # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + # self.coefficients.LUMPED_MASS_MATRIX, + # self.coefficients.STABILIZATION_TYPE, + # self.coefficients.ENTROPY_TYPE, + # # FLUX CORRECTED TRANSPORT + # self.dLow, + # self.fluxMatrix, + # self.uDotLow, + # self.uLow, + # self.dt_times_dC_minus_dL, + # self.min_s_bc, + # self.max_s_bc, + # self.quantDOFs) + #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] + #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf + #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] + #self.timeIntegration.calculateElementCoefficients(self.q) + #if self.forceStrongConditions:# + # for cj in range(len(self.dirichletConditionsForceDOF)):# + # for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): + # r[self.offset[cj]+self.stride[cj]*dofN] = 0 + #if self.stabilization: + # self.stabilization.accumulateSubgridMassHistory(self.q) + #logEvent("Global residual",level=9,data=r) + #self.nonlinear_function_evaluations += 1 + #if self.globalResidualDummy is None: + # self.globalResidualDummy = numpy.zeros(r.shape,'d') + def getJacobian(self,jacobian): + if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG + cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, + jacobian) + degree_polynomial = 1 + try: + degree_polynomial = self.u[0].femSpace.order + except: + pass + if self.delta_x_ij is None: + self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') + argsDict = cArgumentsDict.ArgumentsDict() + argsDict["dt"] = self.timeIntegration.dt + argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi + argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi + argsDict["mesh_dof"] = self.mesh.nodeArray + argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray + argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN + argsDict["mesh_l2g"] = self.mesh.elementNodesArray + argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] + argsDict["u_trial_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi + argsDict["u_test_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi + argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace + argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace + argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] + argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals + argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians + argsDict["nElements_global"] = self.mesh.nElements_global + argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] + argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, + argsDict["isSeepageFace"] = self.coefficients.isSeepageFace + argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] + argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] + argsDict["rho"] = self.coefficients.rho + argsDict["beta"] = self.coefficients.beta + argsDict["gravity"] = self.coefficients.gravity + argsDict["alpha"] = self.coefficients.vgm_alpha_types + argsDict["n"] = self.coefficients.vgm_n_types + argsDict["thetaR"] = self.coefficients.thetaR_types + argsDict["thetaSR"] = self.coefficients.thetaSR_types + argsDict["KWs"] = self.coefficients.Ksw_types + argsDict["useMetrics"] = 0.0 + argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf + argsDict["lag_shockCapturing"] = 0 + argsDict["shockCapturingDiffusion"] = 0.0 + argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g + argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] + argsDict["elementDiameter"] = self.mesh.elementDiametersArray + argsDict["degree_polynomial"] = degree_polynomial + argsDict["u_dof"] = self.u[0].dof + argsDict["velocity"] = self.q['velocity'] + argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] + argsDict["cfl"] = self.q[('cfl',0)] + argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] + argsDict["csrRowIndeces_u_u"] = self.csrRowIndeces[(0,0)] + argsDict["csrColumnOffsets_u_u"] = self.csrColumnOffsets[(0,0)] + argsDict["globalJacobian"] = jacobian.getCSRrepresentation()[2] + argsDict["delta_x_ij"] = self.delta_x_ij + argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global + argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray + argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray + argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray + argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] + argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] + argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] + argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] + argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] + argsDict["csrColumnOffsets_eb_u_u"] = self.csrColumnOffsets_eb[(0,0)] + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + self.calculateJacobian(argsDict) + if self.forceStrongConditions: + for dofN in list(self.dirichletConditionsForceDOF[0].DOFBoundaryConditionsDict.keys()): + global_dofN = self.offset[0]+self.stride[0]*dofN + self.nzval[np.where(self.colind == global_dofN)] = 0.0 #column + self.nzval[self.rowptr[global_dofN]:self.rowptr[global_dofN+1]] = 0.0 #row + zeroRow=True + for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]):#row + if (self.colind[i] == global_dofN): + self.nzval[i] = 1.0 + zeroRow = False + if zeroRow: + raise RuntimeError("Jacobian has a zero row because sparse matrix has no diagonal entry at row "+repr(global_dofN)+". You probably need add diagonal mass or reaction term") + #scaling = 1.0#probably want to add some scaling to match non-dirichlet diagonals in linear system + #for cj in range(self.nc): + # for dofN in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.keys()): + # global_dofN = self.offset[cj]+self.stride[cj]*dofN + # for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]): + # if (self.colind[i] == global_dofN): + # self.nzval[i] = scaling + # else: + # self.nzval[i] = 0.0 + logEvent("Jacobian ",level=10,data=jacobian) + #mwf decide if this is reasonable for solver statistics + self.nonlinear_function_jacobian_evaluations += 1 + return jacobian + def calculateElementQuadrature(self): + """ + Calculate the physical location and weights of the quadrature rules + and the shape information at the quadrature points. + + This function should be called only when the mesh changes. + """ + #self.u[0].femSpace.elementMaps.getValues(self.elementQuadraturePoints, + # self.q['x']) + self.u[0].femSpace.elementMaps.getBasisValuesRef(self.elementQuadraturePoints) + self.u[0].femSpace.elementMaps.getBasisGradientValuesRef(self.elementQuadraturePoints) + self.u[0].femSpace.getBasisValuesRef(self.elementQuadraturePoints) + self.u[0].femSpace.getBasisGradientValuesRef(self.elementQuadraturePoints) + self.coefficients.initializeElementQuadrature(self.timeIntegration.t,self.q) + if self.stabilization != None: + self.stabilization.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) + self.stabilization.initializeTimeIntegration(self.timeIntegration) + if self.shockCapturing != None: + self.shockCapturing.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) + def calculateElementBoundaryQuadrature(self): + pass + def calculateExteriorElementBoundaryQuadrature(self): + """ + Calculate the physical location and weights of the quadrature rules + and the shape information at the quadrature points on global element boundaries. + + This function should be called only when the mesh changes. + """ + # + #get physical locations of element boundary quadrature points + # + #assume all components live on the same mesh + self.u[0].femSpace.elementMaps.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.elementMaps.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.elementMaps.getValuesGlobalExteriorTrace(self.elementBoundaryQuadraturePoints, + self.ebqe['x']) + self.fluxBoundaryConditionsObjectsDict = dict([(cj,FluxBoundaryConditions(self.mesh, + self.nElementBoundaryQuadraturePoints_elementBoundary, + self.ebqe[('x')], + getAdvectiveFluxBoundaryConditions=self.advectiveFluxBoundaryConditionsSetterDict[cj], + getDiffusiveFluxBoundaryConditions=self.diffusiveFluxBoundaryConditionsSetterDictDict[cj])) + for cj in list(self.advectiveFluxBoundaryConditionsSetterDict.keys())]) + self.coefficients.initializeGlobalExteriorElementBoundaryQuadrature(self.timeIntegration.t,self.ebqe) + def estimate_mt(self): + pass + def calculateSolutionAtQuadrature(self): + pass + def calculateAuxiliaryQuantitiesAfterStep(self): + pass diff --git a/richards_fct/richards/__init__.py b/richards_fct/richards/__init__.py new file mode 100644 index 0000000000..c45e66de51 --- /dev/null +++ b/richards_fct/richards/__init__.py @@ -0,0 +1,6 @@ +""" +Modules for simulating variably saturated single-phase flow +""" + +__all__ = ["Richards", + "cRichards"] diff --git a/richards_fct/richards/cRichards.cpp b/richards_fct/richards/cRichards.cpp new file mode 100644 index 0000000000..21c500c55c --- /dev/null +++ b/richards_fct/richards/cRichards.cpp @@ -0,0 +1,36 @@ +#include "pybind11/pybind11.h" +#include "pybind11/stl_bind.h" + +#define FORCE_IMPORT_ARRAY +#include "Richards.h" + +#if defined(__GNUC__) && !defined(__clang__) + namespace workaround + { + inline void define_allocators() + { + std::allocator a0; + std::allocator a1; + } + } +#endif + + +namespace py = pybind11; +using proteus::Richards_base; +PYBIND11_MODULE(cRichards, m) +{ + xt::import_numpy(); + + py::class_(m, "cRichards_base") + .def(py::init(&proteus::newRichards)) + .def("calculateResidual", &Richards_base::calculateResidual) + .def("calculateJacobian", &Richards_base::calculateJacobian) + .def("invert", &Richards_base::invert) + .def("FCTStep", &Richards_base::FCTStep) + .def("kth_FCT_step", &Richards_base::kth_FCT_step) + .def("calculateResidual_entropy_viscosity", &Richards_base::calculateResidual_entropy_viscosity) + .def("calculateMassMatrix", &Richards_base::calculateMassMatrix); +} + + diff --git a/richards_fct/richards/edit/Richards.h.save b/richards_fct/richards/edit/Richards.h.save new file mode 100755 index 0000000000..865f4cbb34 --- /dev/null +++ b/richards_fct/richards/edit/Richards.h.save @@ -0,0 +1,2967 @@ +#ifndef Richards_H +#define Richards_H +#include +#include +#include +#include "CompKernel.h" +#include "ModelFactory.h" +#include "../mprans/ArgumentsDict.h" +#include "xtensor-python/pyarray.hpp" +#define nnz nSpace + +namespace py = pybind11; +#define POWER_SMOOTHNESS_INDICATOR 2 +#define IS_BETAij_ONE 0 +#define GLOBAL_FCT 0 +namespace proteus +{ + // Power entropy // + inline double ENTROPY(const double& phi, const double& phiL, const double& phiR){ + return 1./2.*std::pow(fabs(phi),2.); + } + inline double DENTROPY(const double& phi, const double& phiL, const double& phiR){ + return fabs(phi)*(phi>=0 ? 1 : -1); + } + // Log entropy // for level set from 0 to 1 + inline double ENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ + return std::log(fabs((phi-phiL)*(phiR-phi))+1E-14); + } + inline double DENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ + return (phiL+phiR-2*phi)*((phi-phiL)*(phiR-phi)>=0 ? 1 : -1)/(fabs((phi-phiL)*(phiR-phi))+1E-14); + } +} + +namespace proteus +{ + class Richards_base + { + //The base class defining the interface + public: + virtual ~Richards_base(){} + virtual void calculateResidual(arguments_dict& args)=0; + virtual void calculateJacobian(arguments_dict& args)=0; + virtual void invert(arguments_dict& args)=0; + virtual void FCTStep(arguments_dict& args)=0; + virtual void kth_FCT_step(arguments_dict& args)=0; + virtual void calculateResidual_entropy_viscosity(arguments_dict& args)=0; + virtual void calculateMassMatrix(arguments_dict& args)=0; + }; + + template + class Richards : public Richards_base + { + public: + const int nDOF_test_X_trial_element; + CompKernelType ck; + Richards(): + nDOF_test_X_trial_element(nDOF_test_element*nDOF_trial_element), + ck() + {} + inline + void evaluateCoefficients(const int rowptr[nSpace], + const int colind[nnz], + const double rho, + const double beta, + const double gravity[nSpace], + const double alpha, + const double n_vg, + const double thetaR, + const double thetaSR, + const double KWs[nnz], + const double& u, + double& m, + double& dm, + double f[nSpace], + double df[nSpace], + double a[nnz], + double da[nnz], + double as[nnz], + double& kr, + double& dkr) + { + const int nSpace2 = nSpace * nSpace; + double psiC; + double pcBar; + double pcBar_n; + double pcBar_nM1; + double pcBar_nM2; + double onePlus_pcBar_n; + double sBar; + double sqrt_sBar; + double DsBar_DpsiC; + double thetaW; + double DthetaW_DpsiC; + double vBar; + double vBar2; + double DvBar_DpsiC; + double KWr; + double DKWr_DpsiC; + double rho2 = rho * rho; + double thetaS; + double rhom; + double drhom; + double m_vg; + double pcBarStar; + double sqrt_sBarStar; + + psiC = -u; + m_vg = 1.0 - 1.0 / n_vg; + thetaS = thetaR + thetaSR; + if (psiC > 0.0) + { + pcBar = alpha * psiC; + pcBarStar = pcBar; + if (pcBar < 1.0e-8) + pcBarStar = 1.0e-8; + pcBar_nM2 = pow(pcBarStar, n_vg - 2); + pcBar_nM1 = pcBar_nM2 * pcBar; + pcBar_n = pcBar_nM1 * pcBar; + onePlus_pcBar_n = 1.0 + pcBar_n; + + sBar = pow(onePlus_pcBar_n, -m_vg); + /* using -mn = 1-n */ + DsBar_DpsiC = alpha * (1.0 - n_vg) * (sBar/onePlus_pcBar_n)*pcBar_nM1; + + vBar = 1.0-pcBar_nM1*sBar; + vBar2 = vBar*vBar; + DvBar_DpsiC = -alpha*(n_vg-1.0)*pcBar_nM2*sBar - pcBar_nM1*DsBar_DpsiC; + + thetaW = thetaSR*sBar + thetaR; + DthetaW_DpsiC = thetaSR * DsBar_DpsiC; + + sqrt_sBar = sqrt(sBar); + sqrt_sBarStar = sqrt_sBar; + if (sqrt_sBar < 1.0e-8) + sqrt_sBarStar = 1.0e-8; + KWr= sqrt_sBar*vBar2; + DKWr_DpsiC= ((0.5/sqrt_sBarStar)*DsBar_DpsiC*vBar2 + + + 2.0*sqrt_sBar*vBar*DvBar_DpsiC); + } + else + { + thetaW = thetaS; + DthetaW_DpsiC = 0.0; + KWr = 1.0; + DKWr_DpsiC = 0.0; + } + //slight compressibility + rhom = rho*exp(beta*u); + drhom = beta*rhom; + m = rhom*thetaW; + dm = -rhom*DthetaW_DpsiC+drhom*thetaW; + for (int I=0;I thetaS || thetaW <= thetaR) + { + //cek debug + std::cout<<"rho "< 0.0) + { + isDOFBoundary = 1; + bc_u = bc_u_seepage; + } + else + { + isDOFBoundary = 0; + flux = 0.0; + } + } + /* //set DOF flag and flux correctly if seepage face */ + /* if (isSeepageFace) */ + /* { */ + /* if (flux < 0.0 || u < bc_u_seepage) */ + /* { */ + /* isDOFBoundary = 0; */ + /* flux = 0.0; */ + /* } */ + /* else */ + /* { */ + /* isDOFBoundary = 1; */ + /* bc_u = bc_u_seepage; */ + /* } */ + /* } */ + /* //Dirichlet penalty */ + /* if (isDOFBoundary) */ + /* flux += penalty*(u-bc_u); */ + } + else + flux = bc_flux; + } + + void exteriorNumericalFluxJacobian(const int rowptr[nSpace], + const int colind[nnz], + const int isDOFBoundary, + const double n[nSpace], + const double K[nnz], + const double dK[nnz], + const double grad_psi[nSpace], + const double grad_v[nSpace], + const double dK_rho_g[nSpace], + const double v, + const double penalty, + double& fluxJacobian) + { + if (isDOFBoundary) + { + fluxJacobian = 0.0; + for(int I=0;I& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + double sc_uref = args.scalar("sc_uref"); + double sc_alpha = args.scalar("sc_alpha"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& u_dof_old = args.array("u_dof_old"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m = args.array("q_m"); + xt::pyarray& q_u = args.array("q_u"); + xt::pyarray& q_dV = args.array("q_dV"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + int offset_u = args.scalar("offset_u"); + int stride_u = args.scalar("stride_u"); + xt::pyarray& globalResidual = args.array("globalResidual"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& ebqe_phi = args.array("ebqe_phi"); + double epsFact = args.scalar("epsFact"); + xt::pyarray& ebqe_u = args.array("ebqe_u"); + xt::pyarray& ebqe_flux = args.array("ebqe_flux"); + // PARAMETERS FOR EDGE BASED STABILIZATION + double cE = args.scalar("cE"); + double cK = args.scalar("cK"); + // PARAMETERS FOR LOG BASED ENTROPY FUNCTION + double uL = args.scalar("uL"); + double uR = args.scalar("uR"); + // PARAMETERS FOR EDGE VISCOSITY + int numDOFs = args.scalar("numDOFs"); + int NNZ = args.scalar("NNZ"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); + xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); + xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); + xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); + // C matrices + xt::pyarray& Cx = args.array("Cx"); + xt::pyarray& Cy = args.array("Cy"); + xt::pyarray& Cz = args.array("Cz"); + xt::pyarray& CTx = args.array("CTx"); + xt::pyarray& CTy = args.array("CTy"); + xt::pyarray& CTz = args.array("CTz"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); + int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); + // FOR FCT + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& fluxMatrix = args.array("fluxMatrix"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); + xt::pyarray& min_s_bc = args.array("min_s_bc"); + xt::pyarray& max_s_bc = args.array("max_s_bc"); + // AUX QUANTITIES OF INTEREST + xt::pyarray& quantDOFs = args.array("quantDOFs"); + xt::pyarray& sLow = args.array("sLow"); + xt::pyarray& sn = args.array("sn"); + + assert(a_rowptr.data()[nSpace] == nnz); + assert(a_rowptr.data()[nSpace] == nSpace); + //cek should this be read in? + double Ct_sge = 4.0; + + //loop over elements to compute volume integrals and load them into element and global residual + // + //eN is the element index + //eN_k is the quadrature point index for a scalar + //eN_k_nSpace is the quadrature point index for a vector + //eN_i is the element test function index + //eN_j is the element trial function index + //eN_k_j is the quadrature point index for a trial function + //eN_k_i is the quadrature point index for a trial function + for(int eN=0;eN& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); + xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); + xt::pyarray& globalJacobian = args.array("globalJacobian"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + assert(a_rowptr.data()[nSpace] == nnz); + assert(a_rowptr.data()[nSpace] == nSpace); + double Ct_sge = 4.0; + + // + //loop over elements to compute volume integrals and load them into the element Jacobians and global Jacobian + // + for(int eN=0;eN& bc_mask = args.array("bc_mask"); + int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern + int numDOFs = args.scalar("numDOFs"); //number of DOFs + double dt = args.scalar("dt"); + xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) + xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn + xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn + xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& limited_solution = args.array("limited_solution"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets + xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices + xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 + xt::pyarray& max_s_bc = args.array("max_s_bc"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int MONOLITHIC = args.scalar("MONOLITHIC"); + register double Rpos[numDOFs], Rneg[numDOFs]; + register double FluxCorrectionMatrix[NNZ]; + register double solL[numDOFs]; + register double sdot[numDOFs]; + ////////////////// + // LOOP in DOFs // + ////////////////// + int ij=0; + for (int i=0; i 0) ? 1. : 0.); + Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); + + //update ij + ij+=1; + //std::cout<<"sdoti error"<0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])) + * FluxCorrectionMatrix[ij]; + alpha_dot = fmin(1.0, beta_ij*fabs(alpha_fA)/MassMatrix.data()[ij]/fmax(1.0e-8,fabs(sdoti-sdotj))); + if (MONOLITHIC == 0) + { + ith_Limiter_times_FluxCorrectionMatrix += alpha_fA; + } + else + { + ith_Limiter_times_FluxCorrectionMatrix += alpha_fA + (LUMPED_MASS_MATRIX == 1 ? 0. : 1.)*dt*alpha_dot*MassMatrix.data()[ij]*(sdoti-sdotj); + } + //update ij + ij+=1; + } + limited_solution.data()[i] = solL[i] + 1./lumped_mass_matrix.data()[i]*ith_Limiter_times_FluxCorrectionMatrix*bc_mask[i]; + } + } + + void kth_FCT_step(arguments_dict& args) + { + int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern + int numDOFs = args.scalar("numDOFs"); //number of DOFs + int num_fct_iter = args.scalar("num_fct_iter"); + double dt = args.scalar("dt"); + xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) + xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn + xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn + xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& solLim = args.array("limited_solution"); + xt::pyarray& MC = args.array("MC"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& FluxMatrix = args.array("FluxMatrix"); + xt::pyarray& limitedFlux = args.array("limited_Flux"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets + xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices + xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 + xt::pyarray& max_s_bc = args.array("max_s_bc"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int MONOLITHIC = args.scalar("MONOLITHIC"); + register double Rpos[numDOFs], Rneg[numDOFs]; + int ij=0; + + ////////////////////////////////////////////////////// + // ********** COMPUTE LOW ORDER SOLUTION ********** // + ////////////////////////////////////////////////////// + if (num_fct_iter == 0) + { // No FCT for global bounds + for (int i=0; i 0) ? 1. : 0.); + // update ij + ij+=1; + } + // compute Q vectors + double mi = ML.data()[i]; + double solLimi = solLim.data()[i]; + double Qposi = mi*(maxi-solLimi); + // compute R vectors + Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + } + ij=0; + for (int i=0; i0 ? Rposi : Rpos[j]); + // compute limited flux + ith_Limiter_times_FluxCorrectionMatrix += Lij*Fluxij; + + // update limited flux + limitedFlux.data()[ij] = Lij*Fluxij; + + //update FluxMatrix + FluxMatrix.data()[ij] = Fluxij; + + //update ij + ij+=1; + } + //update limited solution + double mi = ML.data()[i]; + solLim.data()[i] += 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; + } + } + } + + // ***************************************** // + // ********** HIGH ORDER SOLUTION ********** // + // ***************************************** // + ij=0; + for (int i=0; i 0 ? 1. : 0.); + Pnegi += fij * (fij < 0 ? 1. : 0.); + //update ij + ij+=1; + } + // compute Q vectors // + double mi = ML.data()[i]; + double Qposi = mi*(maxi-solLim.data()[i]); + double Qnegi = mi*(mini-solLim.data()[i]); + // compute R vectors // + Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); + } + + // COMPUTE LIMITERS // + ij=0; + for (int i=0; i 0 ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j]); + // compute ith_limited_flux_correction + ith_limited_flux_correction += Lij*fij; + ij+=1; + } + double mi = ML.data()[i]; + solLim[i] += 1./mi*ith_limited_flux_correction; + } + } + + void calculateResidual_entropy_viscosity(arguments_dict& args) + { + xt::pyarray& globalJacobian = args.array("globalJacobian"); + double Theta = args.scalar("Theta"); + xt::pyarray& bc_mask = args.array("bc_mask"); + double dt = args.scalar("dt"); + xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + double sc_uref = args.scalar("sc_uref"); + double sc_alpha = args.scalar("sc_alpha"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& r_l2g = args.array("r_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + int degree_polynomial = args.scalar("degree_polynomial"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& u_dof_old = args.array("u_dof_old"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m = args.array("q_m"); + xt::pyarray& q_u = args.array("q_u"); + xt::pyarray& q_dV = args.array("q_dV"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + int offset_u = args.scalar("offset_u"); + int stride_u = args.scalar("stride_u"); + xt::pyarray& globalResidual = args.array("globalResidual"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& ebqe_phi = args.array("ebqe_phi"); + double epsFact = args.scalar("epsFact"); + xt::pyarray& ebqe_u = args.array("ebqe_u"); + xt::pyarray& ebqe_flux = args.array("ebqe_flux"); + // PARAMETERS FOR EDGE BASED STABILIZATION + double cE = args.scalar("cE"); + double cK = args.scalar("cK"); + // PARAMETERS FOR LOG BASED ENTROPY FUNCTION + double uL = args.scalar("uL"); + double uR = args.scalar("uR"); + // PARAMETERS FOR EDGE VISCOSITY + int numDOFs = args.scalar("numDOFs"); + int NNZ = args.scalar("NNZ"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); + xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); + xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); + xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); + // C matrices + xt::pyarray& Cx = args.array("Cx"); + xt::pyarray& Cy = args.array("Cy"); + xt::pyarray& Cz = args.array("Cz"); + xt::pyarray& CTx = args.array("CTx"); + xt::pyarray& CTy = args.array("CTy"); + xt::pyarray& CTz = args.array("CTz"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); + int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); + // FOR FCT + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& fluxMatrix = args.array("fluxMatrix"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); + xt::pyarray& min_s_bc = args.array("min_s_bc"); + xt::pyarray& max_s_bc = args.array("max_s_bc"); + // AUX QUANTITIES OF INTEREST + xt::pyarray& quantDOFs = args.array("quantDOFs"); + xt::pyarray& sLow = args.array("sLow"); + xt::pyarray& sn = args.array("sn"); + register double Rpos[numDOFs], Rneg[numDOFs]; + //register double FluxCorrectionMatrix[NNZ]; + // NOTE: This function follows a different (but equivalent) implementation of the smoothness based indicator than NCLS.h + // Allocate space for the transport matrices + // This is used for first order KUZMIN'S METHOD + register double TransportMatrix[NNZ],TransportMatrixConsistent[NNZ]; + register double TransportMatrixn[NNZ],TransportMatrixConsistentn[NNZ]; + std::valarray u_free_dof(numDOFs); + std::valarray u_free_dof_old(numDOFs); + std::valarray ML2(numDOFs); + for(int eN=0;eN= 0 && isFluxBoundary_u[ebNE_kb] != 1 ) //outflow. This is handled via the transport matrices. Then flux_ext=0 and dflux_ext!=0 */ + /* { */ + /* dflux_ext = flow; */ + /* flux_ext = 0; */ + /* // save external u */ + /* ebqe_u[ebNE_kb] = u_ext; */ + /* } */ + /* else // inflow. This is handled via the boundary integral. Then flux_ext!=0 and dflux_ext=0 */ + /* { */ + /* dflux_ext = 0; */ + /* // save external u */ + /* ebqe_u[ebNE_kb] = isDOFBoundary_u[ebNE_kb]*ebqe_bc_u_ext[ebNE_kb]+(1-isDOFBoundary_u[ebNE_kb])*u_ext; */ + /* if (isDOFBoundary_u[ebNE_kb] == 1) */ + /* flux_ext = ebqe_bc_u_ext[ebNE_kb]*flow; */ + /* else if (isFluxBoundary_u[ebNE_kb] == 1) */ + /* flux_ext = ebqe_bc_flux_u_ext[ebNE_kb]; */ + /* else */ + /* { */ + /* std::cout<<"warning: VOF open boundary with no external trace, setting to zero for inflow"<= 0.) + { + alpha_numerator_pos += alpha_num; + alpha_denominator_pos += alpha_num; + } + else + { + alpha_numerator_neg += alpha_num; + alpha_denominator_neg += fabs(alpha_num); + } + //update ij + ij+=1; + } + // scale g vector by lumped mass matrix + if (fabs(ML.data()[i] - ML2[i]) > 1.0e-16) + std::cout<<"ML "< 0.0) + // assert( (xi[I] - xj[I]) == delta_x_ij[offset*3+I]); + //gi_times_x += gi[I]*(xi[I]-xj[I]); + gi_times_x += gi[I]*delta_x_ij.data()[offset*3+I]; + } + // compute the positive and negative part of gi*(xi-xj) + SumPos += gi_times_x > 0 ? gi_times_x : 0; + SumNeg += gi_times_x < 0 ? gi_times_x : 0; + } + double sigmaPosi = fmin(1.,(fabs(SumNeg)+1E-15)/(SumPos+1E-15)); + double sigmaNegi = fmin(1.,(SumPos+1E-15)/(fabs(SumNeg)+1E-15)); + double alpha_numi = fabs(sigmaPosi*alpha_numerator_pos + sigmaNegi*alpha_numerator_neg); + double alpha_deni = sigmaPosi*alpha_denominator_pos + sigmaNegi*alpha_denominator_neg; + if (IS_BETAij_ONE == 1) + { + alpha_numi = fabs(alpha_numerator_pos + alpha_numerator_neg); + alpha_deni = alpha_denominator_pos + alpha_denominator_neg; + } + double alphai = alpha_numi/(alpha_deni+1E-15); + quantDOFs.data()[i] = alphai; + + if (POWER_SMOOTHNESS_INDICATOR==0) + psi[i] = 1.0; + else + psi[i] = std::pow(alphai,POWER_SMOOTHNESS_INDICATOR); //NOTE: they use alpha^2 in the paper + } + ///////////////////////////////////////////// + // ** LOOP IN DOFs FOR EDGE BASED TERMS ** // + ///////////////////////////////////////////// + ij=0; + for (int i=0; i Dissipation matrices as well. + double soli = u_free_dof[i]; // solution at time tn for the ith DOF + double solni = u_free_dof_old[i]; // solution at time tn for the ith DOF + for (int I=0;I mMax) + { + std::cout<<"mass out of bounds "< 0) ? 1. : 0.); + // Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); + // ij+=1; + // } + // double mi = ML[i]; + // double solni = u_dof_old[i]; + // double Qposi = mi*(maxi-solni); + // double Qnegi = mi*(mini-solni); + + //std::cout << Qposi << std::endl; + // Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + // Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); + + //if (Rpos[i] < 0) + //{ + // std::cout << mi << "\t" << maxi << "\t" << solni << std::endl; + // std::cout << Qposi << "\t" << Pposi << std::endl; + // std::cout << Rpos[i] << std::endl; + //abort(); + //} + //} + + //ij=0; + //for (int i=0; i 1.0 || Rposi < 0.0) + //std::cout << "Rposi: " << Rposi << std::endl; + //if (Rnegi > 1.0 || Rnegi < 0.0) + //std::cout << "Rnegi: " << Rnegi << std::endl; + + // LOOP OVER THE SPARSITY PATTERN (j-LOOP)// + // for (int offset=csrRowIndeces_DofLoops.data()[i]; + // offset0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])); + // //Lij=0.0; + // ith_Limiter_times_FluxCorrectionMatrix += Lij*FluxCorrectionMatrix[ij]; + // //update ij + // ij+=1; + // } + // double mi = ML[i]; + // double solni = u_dof_old[i]; + // globalResidual[i] = solni + 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; + //} + + } + + void invert(arguments_dict& args) + { + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + xt::pyarray& globalResidual = args.array("globalResidual"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + int numDOFs = args.scalar("numDOFs"); + for (int i=0; i mMax) + { + std::cout<<"mass out of bounds "<("dt"); + xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + //element boundary + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + //physics + int nElements_global = args.scalar("nElements_global"); + //new + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + //end new + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& r_l2g = args.array("r_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + int degree_polynomial = args.scalar("degree_polynomial"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); + xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); + xt::pyarray& globalJacobian = args.array("globalJacobian"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + //std::cout<<"ndjaco address "<(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + else if (nSpaceIn == 2) + return proteus::chooseAndAllocateDiscretization2D(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + else + { + assert(nSpaceIn == 3); + return proteus::chooseAndAllocateDiscretization(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + } + } +}//proteus +#endif \ No newline at end of file diff --git a/richards_fct/richards/edit/Richards.h.save.1 b/richards_fct/richards/edit/Richards.h.save.1 new file mode 100755 index 0000000000..bda6e99948 --- /dev/null +++ b/richards_fct/richards/edit/Richards.h.save.1 @@ -0,0 +1,2970 @@ +#ifndef Richards_H +#define Richards_H +#include +#include +#include +#include "CompKernel.h" +#include "ModelFactory.h" +#include "../mprans/ArgumentsDict.h" +#include "xtensor-python/pyarray.hpp" +#define nnz nSpace + +namespace py = pybind11; +#define POWER_SMOOTHNESS_INDICATOR 2 +#define IS_BETAij_ONE 0 +#define GLOBAL_FCT 0 +namespace proteus +{ + // Power entropy // + inline double ENTROPY(const double& phi, const double& phiL, const double& phiR){ + return 1./2.*std::pow(fabs(phi),2.); + } + inline double DENTROPY(const double& phi, const double& phiL, const double& phiR){ + return fabs(phi)*(phi>=0 ? 1 : -1); + } + // Log entropy // for level set from 0 to 1 + inline double ENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ + return std::log(fabs((phi-phiL)*(phiR-phi))+1E-14); + } + inline double DENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ + return (phiL+phiR-2*phi)*((phi-phiL)*(phiR-phi)>=0 ? 1 : -1)/(fabs((phi-phiL)*(phiR-phi))+1E-14); + } +} + +namespace proteus +{ + class Richards_base + { + //The base class defining the interface + public: + virtual ~Richards_base(){} + virtual void calculateResidual(arguments_dict& args)=0; + virtual void calculateJacobian(arguments_dict& args)=0; + virtual void invert(arguments_dict& args)=0; + virtual void FCTStep(arguments_dict& args)=0; + virtual void kth_FCT_step(arguments_dict& args)=0; + virtual void calculateResidual_entropy_viscosity(arguments_dict& args)=0; + virtual void calculateMassMatrix(arguments_dict& args)=0; + }; + + template + class Richards : public Richards_base + { + public: + const int nDOF_test_X_trial_element; + CompKernelType ck; + Richards(): + nDOF_test_X_trial_element(nDOF_test_element*nDOF_trial_element), + ck() + {} + inline + void evaluateCoefficients(const int rowptr[nSpace], + const int colind[nnz], + const double rho, + const double beta, + const double gravity[nSpace], + const double alpha, + const double n_vg, + const double thetaR, + const double thetaSR, + const double KWs[nnz], + const double& u, + double& m, + double& dm, + double f[nSpace], + double df[nSpace], + double a[nnz], + double da[nnz], + double as[nnz], + double& kr, + double& dkr) + { + const int nSpace2 = nSpace * nSpace; + double psiC; + double pcBar; + double pcBar_n; + double pcBar_nM1; + double pcBar_nM2; + double onePlus_pcBar_n; + double sBar; + double sqrt_sBar; + double DsBar_DpsiC; + double thetaW; + double DthetaW_DpsiC; + double vBar; + double vBar2; + double DvBar_DpsiC; + double KWr; + double DKWr_DpsiC; + double rho2 = rho * rho; + double thetaS; + double rhom; + double drhom; + double m_vg; + double pcBarStar; + double sqrt_sBarStar; + + psiC = -u; + m_vg = 1.0 - 1.0 / n_vg; + thetaS = thetaR + thetaSR; + if (psiC > 0.0) + { + pcBar = alpha * psiC; + pcBarStar = pcBar; + if (pcBar < 1.0e-8) + pcBarStar = 1.0e-8; + pcBar_nM2 = pow(pcBarStar, n_vg - 2); + pcBar_nM1 = pcBar_nM2 * pcBar; + pcBar_n = pcBar_nM1 * pcBar; + onePlus_pcBar_n = 1.0 + pcBar_n; + + sBar = pow(onePlus_pcBar_n, -m_vg); + /* using -mn = 1-n */ + DsBar_DpsiC = alpha * (1.0 - n_vg) * (sBar/onePlus_pcBar_n)*pcBar_nM1; + + vBar = 1.0-pcBar_nM1*sBar; + vBar2 = vBar*vBar; + DvBar_DpsiC = -alpha*(n_vg-1.0)*pcBar_nM2*sBar - pcBar_nM1*DsBar_DpsiC; + + thetaW = thetaSR*sBar + thetaR; + DthetaW_DpsiC = thetaSR * DsBar_DpsiC; + + sqrt_sBar = sqrt(sBar); + sqrt_sBarStar = sqrt_sBar; + if (sqrt_sBar < 1.0e-8) + sqrt_sBarStar = 1.0e-8; + KWr= sqrt_sBar*vBar2; + DKWr_DpsiC= ((0.5/sqrt_sBarStar)*DsBar_DpsiC*vBar2 + + + 2.0*sqrt_sBar*vBar*DvBar_DpsiC); + } + else + { + thetaW = thetaS; + DthetaW_DpsiC = 0.0; + KWr = 1.0; + DKWr_DpsiC = 0.0; + } + //slight compressibility + rhom = rho*exp(beta*u); + drhom = beta*rhom; + m = rhom*thetaW; + dm = -rhom*DthetaW_DpsiC+drhom*thetaW; + for (int I=0;I thetaS || thetaW <= thetaR) + { + //cek debug + std::cout<<"rho "< 0.0) + { + isDOFBoundary = 1; + bc_u = bc_u_seepage; + } + else + { + isDOFBoundary = 0; + flux = 0.0; + } + } + /* //set DOF flag and flux correctly if seepage face */ + /* if (isSeepageFace) */ + /* { */ + /* if (flux < 0.0 || u < bc_u_seepage) */ + /* { */ + /* isDOFBoundary = 0; */ + /* flux = 0.0; */ + /* } */ + /* else */ + /* { */ + /* isDOFBoundary = 1; */ + /* bc_u = bc_u_seepage; */ + /* } */ + /* } */ + /* //Dirichlet penalty */ + /* if (isDOFBoundary) */ + /* flux += penalty*(u-bc_u); */ + } + else + flux = bc_flux; + } + + void exteriorNumericalFluxJacobian(const int rowptr[nSpace], + const int colind[nnz], + const int isDOFBoundary, + const double n[nSpace], + const double K[nnz], + const double dK[nnz], + const double grad_psi[nSpace], + const double grad_v[nSpace], + const double dK_rho_g[nSpace], + const double v, + const double penalty, + double& fluxJacobian) + { + if (isDOFBoundary) + { + fluxJacobian = 0.0; + for(int I=0;I& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + double sc_uref = args.scalar("sc_uref"); + double sc_alpha = args.scalar("sc_alpha"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& u_dof_old = args.array("u_dof_old"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m = args.array("q_m"); + xt::pyarray& q_u = args.array("q_u"); + xt::pyarray& q_dV = args.array("q_dV"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + int offset_u = args.scalar("offset_u"); + int stride_u = args.scalar("stride_u"); + xt::pyarray& globalResidual = args.array("globalResidual"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& ebqe_phi = args.array("ebqe_phi"); + double epsFact = args.scalar("epsFact"); + xt::pyarray& ebqe_u = args.array("ebqe_u"); + xt::pyarray& ebqe_flux = args.array("ebqe_flux"); + // PARAMETERS FOR EDGE BASED STABILIZATION + double cE = args.scalar("cE"); + double cK = args.scalar("cK"); + // PARAMETERS FOR LOG BASED ENTROPY FUNCTION + double uL = args.scalar("uL"); + double uR = args.scalar("uR"); + // PARAMETERS FOR EDGE VISCOSITY + int numDOFs = args.scalar("numDOFs"); + int NNZ = args.scalar("NNZ"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); + xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); + xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); + xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); + // C matrices + xt::pyarray& Cx = args.array("Cx"); + xt::pyarray& Cy = args.array("Cy"); + xt::pyarray& Cz = args.array("Cz"); + xt::pyarray& CTx = args.array("CTx"); + xt::pyarray& CTy = args.array("CTy"); + xt::pyarray& CTz = args.array("CTz"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); + int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); + // FOR FCT + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& fluxMatrix = args.array("fluxMatrix"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); + xt::pyarray& min_s_bc = args.array("min_s_bc"); + xt::pyarray& max_s_bc = args.array("max_s_bc"); + // AUX QUANTITIES OF INTEREST + xt::pyarray& quantDOFs = args.array("quantDOFs"); + xt::pyarray& sLow = args.array("sLow"); + xt::pyarray& sn = args.array("sn"); + + assert(a_rowptr.data()[nSpace] == nnz); + assert(a_rowptr.data()[nSpace] == nSpace); + //cek should this be read in? + double Ct_sge = 4.0; + + //loop over elements to compute volume integrals and load them into element and global residual + // + //eN is the element index + //eN_k is the quadrature point index for a scalar + //eN_k_nSpace is the quadrature point index for a vector + //eN_i is the element test function index + //eN_j is the element trial function index + //eN_k_j is the quadrature point index for a trial function + //eN_k_i is the quadrature point index for a trial function + for(int eN=0;eN& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); + xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); + xt::pyarray& globalJacobian = args.array("globalJacobian"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + assert(a_rowptr.data()[nSpace] == nnz); + assert(a_rowptr.data()[nSpace] == nSpace); + double Ct_sge = 4.0; + + // + //loop over elements to compute volume integrals and load them into the element Jacobians and global Jacobian + // + for(int eN=0;eN& bc_mask = args.array("bc_mask"); + int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern + int numDOFs = args.scalar("numDOFs"); //number of DOFs + double dt = args.scalar("dt"); + xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) + xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn + xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn + xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& limited_solution = args.array("limited_solution"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets + xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices + xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 + xt::pyarray& max_s_bc = args.array("max_s_bc"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int MONOLITHIC = args.scalar("MONOLITHIC"); + register double Rpos[numDOFs], Rneg[numDOFs]; + register double FluxCorrectionMatrix[NNZ]; + register double solL[numDOFs]; + register double sdot[numDOFs]; + ////////////////// + // LOOP in DOFs // + ////////////////// + int ij=0; + for (int i=0; i 0) ? 1. : 0.); + Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); + + //update ij + ij+=1; + //std::cout<<"sdoti error"<0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])) + * FluxCorrectionMatrix[ij]; + alpha_dot = fmin(1.0, beta_ij*fabs(alpha_fA)/MassMatrix.data()[ij]/fmax(1.0e-8,fabs(sdoti-sdotj))); + if (MONOLITHIC == 0) + { + ith_Limiter_times_FluxCorrectionMatrix += alpha_fA; + } + else + { + ith_Limiter_times_FluxCorrectionMatrix += alpha_fA + (LUMPED_MASS_MATRIX == 1 ? 0. : 1.)*dt*alpha_dot*MassMatrix.data()[ij]*(sdoti-sdotj); + } + //update ij + ij+=1; + } + limited_solution.data()[i] = solL[i] + 1./lumped_mass_matrix.data()[i]*ith_Limiter_times_FluxCorrectionMatrix*bc_mask[i]; + } + } + + void kth_FCT_step(arguments_dict& args) + { + int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern + int numDOFs = args.scalar("numDOFs"); //number of DOFs + int num_fct_iter = args.scalar("num_fct_iter"); + double dt = args.scalar("dt"); + xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) + xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn + xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn + xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& solLim = args.array("limited_solution"); + xt::pyarray& MC = args.array("MC"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& FluxMatrix = args.array("FluxMatrix"); + xt::pyarray& limitedFlux = args.array("limited_Flux"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets + xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices + xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 + xt::pyarray& max_s_bc = args.array("max_s_bc"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int MONOLITHIC = args.scalar("MONOLITHIC"); + register double Rpos[numDOFs], Rneg[numDOFs]; + int ij=0; + + ////////////////////////////////////////////////////// + // ********** COMPUTE LOW ORDER SOLUTION ********** // + ////////////////////////////////////////////////////// + if (num_fct_iter == 0) + { // No FCT for global bounds + for (int i=0; i 0) ? 1. : 0.); + // update ij + ij+=1; + } + // compute Q vectors + double mi = ML.data()[i]; + double solLimi = solLim.data()[i]; + double Qposi = mi*(maxi-solLimi); + // compute R vectors + Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + } + ij=0; + for (int i=0; i0 ? Rposi : Rpos[j]); + // compute limited flux + ith_Limiter_times_FluxCorrectionMatrix += Lij*Fluxij; + + // update limited flux + limitedFlux.data()[ij] = Lij*Fluxij; + + //update FluxMatrix + FluxMatrix.data()[ij] = Fluxij; + + //update ij + ij+=1; + } + //update limited solution + double mi = ML.data()[i]; + solLim.data()[i] += 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; + } + } + } + + // ***************************************** // + // ********** HIGH ORDER SOLUTION ********** // + // ***************************************** // + ij=0; + for (int i=0; i 0 ? 1. : 0.); + Pnegi += fij * (fij < 0 ? 1. : 0.); + //update ij + ij+=1; + } + // compute Q vectors // + double mi = ML.data()[i]; + double Qposi = mi*(maxi-solLim.data()[i]); + double Qnegi = mi*(mini-solLim.data()[i]); + // compute R vectors // + Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); + } + + // COMPUTE LIMITERS // + ij=0; + for (int i=0; i 0 ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j]); + // compute ith_limited_flux_correction + ith_limited_flux_correction += Lij*fij; + ij+=1; + } + double mi = ML.data()[i]; + solLim[i] += 1./mi*ith_limited_flux_correction; + } + } + + void calculateResidual_entropy_viscosity(arguments_dict& args) + { + xt::pyarray& globalJacobian = args.array("globalJacobian"); + double Theta = args.scalar("Theta"); + xt::pyarray& bc_mask = args.array("bc_mask"); + double dt = args.scalar("dt"); + xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + double sc_uref = args.scalar("sc_uref"); + double sc_alpha = args.scalar("sc_alpha"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& r_l2g = args.array("r_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + int degree_polynomial = args.scalar("degree_polynomial"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& u_dof_old = args.array("u_dof_old"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m = args.array("q_m"); + xt::pyarray& q_u = args.array("q_u"); + xt::pyarray& q_dV = args.array("q_dV"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + int offset_u = args.scalar("offset_u"); + int stride_u = args.scalar("stride_u"); + xt::pyarray& globalResidual = args.array("globalResidual"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& ebqe_phi = args.array("ebqe_phi"); + double epsFact = args.scalar("epsFact"); + xt::pyarray& ebqe_u = args.array("ebqe_u"); + xt::pyarray& ebqe_flux = args.array("ebqe_flux"); + // PARAMETERS FOR EDGE BASED STABILIZATION + double cE = args.scalar("cE"); + double cK = args.scalar("cK"); + // PARAMETERS FOR LOG BASED ENTROPY FUNCTION + double uL = args.scalar("uL"); + double uR = args.scalar("uR"); + // PARAMETERS FOR EDGE VISCOSITY + int numDOFs = args.scalar("numDOFs"); + int NNZ = args.scalar("NNZ"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); + xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); + xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); + xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); + // C matrices + xt::pyarray& Cx = args.array("Cx"); + xt::pyarray& Cy = args.array("Cy"); + xt::pyarray& Cz = args.array("Cz"); + xt::pyarray& CTx = args.array("CTx"); + xt::pyarray& CTy = args.array("CTy"); + xt::pyarray& CTz = args.array("CTz"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); + int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); + // FOR FCT + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& fluxMatrix = args.array("fluxMatrix"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); + xt::pyarray& min_s_bc = args.array("min_s_bc"); + xt::pyarray& max_s_bc = args.array("max_s_bc"); + // AUX QUANTITIES OF INTEREST + xt::pyarray& quantDOFs = args.array("quantDOFs"); + xt::pyarray& sLow = args.array("sLow"); + xt::pyarray& sn = args.array("sn"); + register double Rpos[numDOFs], Rneg[numDOFs]; + //register double FluxCorrectionMatrix[NNZ]; + // NOTE: This function follows a different (but equivalent) implementation of the smoothness based indicator than NCLS.h + // Allocate space for the transport matrices + // This is used for first order KUZMIN'S METHOD + register double TransportMatrix[NNZ],TransportMatrixConsistent[NNZ]; + register double TransportMatrixn[NNZ],TransportMatrixConsistentn[NNZ]; + std::valarray u_free_dof(numDOFs); + std::valarray u_free_dof_old(numDOFs); + std::valarray ML2(numDOFs); + for(int eN=0;eN= 0 && isFluxBoundary_u[ebNE_kb] != 1 ) //outflow. This is handled via the transport matrices. Then flux_ext=0 and dflux_ext!=0 */ + /* { */ + /* dflux_ext = flow; */ + /* flux_ext = 0; */ + /* // save external u */ + /* ebqe_u[ebNE_kb] = u_ext; */ + /* } */ + /* else // inflow. This is handled via the boundary integral. Then flux_ext!=0 and dflux_ext=0 */ + /* { */ + /* dflux_ext = 0; */ + /* // save external u */ + /* ebqe_u[ebNE_kb] = isDOFBoundary_u[ebNE_kb]*ebqe_bc_u_ext[ebNE_kb]+(1-isDOFBoundary_u[ebNE_kb])*u_ext; */ + /* if (isDOFBoundary_u[ebNE_kb] == 1) */ + /* flux_ext = ebqe_bc_u_ext[ebNE_kb]*flow; */ + /* else if (isFluxBoundary_u[ebNE_kb] == 1) */ + /* flux_ext = ebqe_bc_flux_u_ext[ebNE_kb]; */ + /* else */ + /* { */ + /* std::cout<<"warning: VOF open boundary with no external trace, setting to zero for inflow"<= 0.) + { + alpha_numerator_pos += alpha_num; + alpha_denominator_pos += alpha_num; + } + else + { + alpha_numerator_neg += alpha_num; + alpha_denominator_neg += fabs(alpha_num); + } + //update ij + ij+=1; + } + // scale g vector by lumped mass matrix + if (fabs(ML.data()[i] - ML2[i]) > 1.0e-16) + std::cout<<"ML "< 0.0) + // assert( (xi[I] - xj[I]) == delta_x_ij[offset*3+I]); + //gi_times_x += gi[I]*(xi[I]-xj[I]); + gi_times_x += gi[I]*delta_x_ij.data()[offset*3+I]; + } + // compute the positive and negative part of gi*(xi-xj) + SumPos += gi_times_x > 0 ? gi_times_x : 0; + SumNeg += gi_times_x < 0 ? gi_times_x : 0; + } + double sigmaPosi = fmin(1.,(fabs(SumNeg)+1E-15)/(SumPos+1E-15)); + double sigmaNegi = fmin(1.,(SumPos+1E-15)/(fabs(SumNeg)+1E-15)); + double alpha_numi = fabs(sigmaPosi*alpha_numerator_pos + sigmaNegi*alpha_numerator_neg); + double alpha_deni = sigmaPosi*alpha_denominator_pos + sigmaNegi*alpha_denominator_neg; + if (IS_BETAij_ONE == 1) + { + alpha_numi = fabs(alpha_numerator_pos + alpha_numerator_neg); + alpha_deni = alpha_denominator_pos + alpha_denominator_neg; + } + double alphai = alpha_numi/(alpha_deni+1E-15); + quantDOFs.data()[i] = alphai; + + if (POWER_SMOOTHNESS_INDICATOR==0) + psi[i] = 1.0; + else + psi[i] = std::pow(alphai,POWER_SMOOTHNESS_INDICATOR); //NOTE: they use alpha^2 in the paper + } + ///////////////////////////////////////////// + // ** LOOP IN DOFs FOR EDGE BASED TERMS ** // + ///////////////////////////////////////////// + ij=0; + for (int i=0; i Dissipation matrices as well. + double soli = u_free_dof[i]; // solution at time tn for the ith DOF + double solni = u_free_dof_old[i]; // solution at time tn for the ith DOF + for (int I=0;I mMax) + { + std::cout<<"mass out of bounds "< 0) ? 1. : 0.); + // Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); + // ij+=1; + // } + // double mi = ML[i]; + // double solni = u_dof_old[i]; + // double Qposi = mi*(maxi-solni); + // double Qnegi = mi*(mini-solni); + + //std::cout << Qposi << std::endl; + // Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + // Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); + + //if (Rpos[i] < 0) + //{ + // std::cout << mi << "\t" << maxi << "\t" << solni << std::endl; + // std::cout << Qposi << "\t" << Pposi << std::endl; + // std::cout << Rpos[i] << std::endl; + //abort(); + //} + //} + + //ij=0; + //for (int i=0; i 1.0 || Rposi < 0.0) + //std::cout << "Rposi: " << Rposi << std::endl; + //if (Rnegi > 1.0 || Rnegi < 0.0) + //std::cout << "Rnegi: " << Rnegi << std::endl; + + // LOOP OVER THE SPARSITY PATTERN (j-LOOP)// + // for (int offset=csrRowIndeces_DofLoops.data()[i]; + // offset0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])); + // //Lij=0.0; + // ith_Limiter_times_FluxCorrectionMatrix += Lij*FluxCorrectionMatrix[ij]; + // //update ij + // ij+=1; + // } + // double mi = ML[i]; + // double solni = u_dof_old[i]; + // globalResidual[i] = solni + 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; + //} + + } + + void invert(arguments_dict& args) + { + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + xt::pyarray& globalResidual = args.array("globalResidual"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + int numDOFs = args.scalar("numDOFs"); + for (int i=0; i mMax) + { + std::cout<<"mass out of bounds "<("dt"); + xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + //element boundary + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + //physics + int nElements_global = args.scalar("nElements_global"); + //new + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + //end new + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& r_l2g = args.array("r_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + int degree_polynomial = args.scalar("degree_polynomial"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); + xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); + xt::pyarray& globalJacobian = args.array("globalJacobian"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + //std::cout<<"ndjaco address "<(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + else if (nSpaceIn == 2) + return proteus::chooseAndAllocateDiscretization2D(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + else + { + assert(nSpaceIn == 3); + return proteus::chooseAndAllocateDiscretization(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + } + } +}//proteus +#endif diff --git a/richards_fct/richards/edit/Richards.h:Zone.Identifier b/richards_fct/richards/edit/Richards.h:Zone.Identifier new file mode 100644 index 0000000000..1bf0b28e7b --- /dev/null +++ b/richards_fct/richards/edit/Richards.h:Zone.Identifier @@ -0,0 +1,3 @@ +[ZoneTransfer] +ZoneId=3 +HostUrl=https://github.com/ diff --git a/richards_fct/richards/edit/Richards.py:Zone.Identifier b/richards_fct/richards/edit/Richards.py:Zone.Identifier new file mode 100644 index 0000000000..1bf0b28e7b --- /dev/null +++ b/richards_fct/richards/edit/Richards.py:Zone.Identifier @@ -0,0 +1,3 @@ +[ZoneTransfer] +ZoneId=3 +HostUrl=https://github.com/ diff --git a/richards_fct/richards/edit/Richards_abc.h b/richards_fct/richards/edit/Richards_abc.h new file mode 100644 index 0000000000..c871014017 --- /dev/null +++ b/richards_fct/richards/edit/Richards_abc.h @@ -0,0 +1,2967 @@ + +#ifndef Richards_H +#define Richards_H +#include +#include +#include +#include "CompKernel.h" +#include "ModelFactory.h" +#include "../mprans/ArgumentsDict.h" +#include "xtensor-python/pyarray.hpp" +#define nnz nSpace + +namespace py = pybind11; +#define POWER_SMOOTHNESS_INDICATOR 2 +#define IS_BETAij_ONE 0 +#define GLOBAL_FCT 0 +namespace proteus +{ + // Power entropy // + inline double ENTROPY(const double& phi, const double& phiL, const double& phiR){ + return 1./2.*std::pow(fabs(phi),2.); + } + inline double DENTROPY(const double& phi, const double& phiL, const double& phiR){ + return fabs(phi)*(phi>=0 ? 1 : -1); + } + // Log entropy // for level set from 0 to 1 + inline double ENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ + return std::log(fabs((phi-phiL)*(phiR-phi))+1E-14); + } + inline double DENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ + return (phiL+phiR-2*phi)*((phi-phiL)*(phiR-phi)>=0 ? 1 : -1)/(fabs((phi-phiL)*(phiR-phi))+1E-14); + } +} + +namespace proteus +{ + class Richards_base + { + //The base class defining the interface + public: + virtual ~Richards_base(){} + virtual void calculateResidual(arguments_dict& args)=0; + virtual void calculateJacobian(arguments_dict& args)=0; + virtual void invert(arguments_dict& args)=0; + virtual void FCTStep(arguments_dict& args)=0; + virtual void kth_FCT_step(arguments_dict& args)=0; + virtual void calculateResidual_entropy_viscosity(arguments_dict& args)=0; + virtual void calculateMassMatrix(arguments_dict& args)=0; + }; + + template + class Richards : public Richards_base + { + public: + const int nDOF_test_X_trial_element; + CompKernelType ck; + Richards(): + nDOF_test_X_trial_element(nDOF_test_element*nDOF_trial_element), + ck() + {} + inline + void evaluateCoefficients(const int rowptr[nSpace], + const int colind[nnz], + const double rho, + const double beta, + const double gravity[nSpace], + const double alpha, + const double n_vg, + const double thetaR, + const double thetaSR, + const double KWs[nnz], + const double& u, + double& m, + double& dm, + double f[nSpace], + double df[nSpace], + double a[nnz], + double da[nnz], + double as[nnz], + double& kr, + double& dkr) + { + const int nSpace2 = nSpace * nSpace; + double psiC; + double pcBar; + double pcBar_n; + double pcBar_nM1; + double pcBar_nM2; + double onePlus_pcBar_n; + double sBar; + double sqrt_sBar; + double DsBar_DpsiC; + double thetaW; + double DthetaW_DpsiC; + double vBar; + double vBar2; + double DvBar_DpsiC; + double KWr; + double DKWr_DpsiC; + double rho2 = rho * rho; + double thetaS; + double rhom; + double drhom; + double m_vg; + double pcBarStar; + double sqrt_sBarStar; + + psiC = -u; + m_vg = 1.0 - 1.0 / n_vg; + thetaS = thetaR + thetaSR; + if (psiC > 0.0) + { + pcBar = alpha * psiC; + pcBarStar = pcBar; + if (pcBar < 1.0e-8) + pcBarStar = 1.0e-8; + pcBar_nM2 = pow(pcBarStar, n_vg - 2); + pcBar_nM1 = pcBar_nM2 * pcBar; + pcBar_n = pcBar_nM1 * pcBar; + onePlus_pcBar_n = 1.0 + pcBar_n; + + sBar = pow(onePlus_pcBar_n, -m_vg); + /* using -mn = 1-n */ + DsBar_DpsiC = alpha * (1.0 - n_vg) * (sBar/onePlus_pcBar_n)*pcBar_nM1; + + vBar = 1.0-pcBar_nM1*sBar; + vBar2 = vBar*vBar; + DvBar_DpsiC = -alpha*(n_vg-1.0)*pcBar_nM2*sBar - pcBar_nM1*DsBar_DpsiC; + + thetaW = thetaSR*sBar + thetaR; + DthetaW_DpsiC = thetaSR * DsBar_DpsiC; + + sqrt_sBar = sqrt(sBar); + sqrt_sBarStar = sqrt_sBar; + if (sqrt_sBar < 1.0e-8) + sqrt_sBarStar = 1.0e-8; + KWr= sqrt_sBar*vBar2; + DKWr_DpsiC= ((0.5/sqrt_sBarStar)*DsBar_DpsiC*vBar2 + + + 2.0*sqrt_sBar*vBar*DvBar_DpsiC); + } + else + { + thetaW = thetaS; + DthetaW_DpsiC = 0.0; + KWr = 1.0; + DKWr_DpsiC = 0.0; + } + //slight compressibility + rhom = rho*exp(beta*u); + drhom = beta*rhom; + m = rhom*thetaW; + dm = -rhom*DthetaW_DpsiC+drhom*thetaW; + for (int I=0;I thetaS || thetaW <= thetaR) + { + //cek debug + std::cout<<"rho "< 0.0) + { + isDOFBoundary = 1; + bc_u = bc_u_seepage; + } + else + { + isDOFBoundary = 0; + flux = 0.0; + } + } + /* //set DOF flag and flux correctly if seepage face */ + /* if (isSeepageFace) */ + /* { */ + /* if (flux < 0.0 || u < bc_u_seepage) */ + /* { */ + /* isDOFBoundary = 0; */ + /* flux = 0.0; */ + /* } */ + /* else */ + /* { */ + /* isDOFBoundary = 1; */ + /* bc_u = bc_u_seepage; */ + /* } */ + /* } */ + /* //Dirichlet penalty */ + /* if (isDOFBoundary) */ + /* flux += penalty*(u-bc_u); */ + } + else + flux = bc_flux; + } + + void exteriorNumericalFluxJacobian(const int rowptr[nSpace], + const int colind[nnz], + const int isDOFBoundary, + const double n[nSpace], + const double K[nnz], + const double dK[nnz], + const double grad_psi[nSpace], + const double grad_v[nSpace], + const double dK_rho_g[nSpace], + const double v, + const double penalty, + double& fluxJacobian) + { + if (isDOFBoundary) + { + fluxJacobian = 0.0; + for(int I=0;I& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + double sc_uref = args.scalar("sc_uref"); + double sc_alpha = args.scalar("sc_alpha"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& u_dof_old = args.array("u_dof_old"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m = args.array("q_m"); + xt::pyarray& q_u = args.array("q_u"); + xt::pyarray& q_dV = args.array("q_dV"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + int offset_u = args.scalar("offset_u"); + int stride_u = args.scalar("stride_u"); + xt::pyarray& globalResidual = args.array("globalResidual"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& ebqe_phi = args.array("ebqe_phi"); + double epsFact = args.scalar("epsFact"); + xt::pyarray& ebqe_u = args.array("ebqe_u"); + xt::pyarray& ebqe_flux = args.array("ebqe_flux"); + // PARAMETERS FOR EDGE BASED STABILIZATION + double cE = args.scalar("cE"); + double cK = args.scalar("cK"); + // PARAMETERS FOR LOG BASED ENTROPY FUNCTION + double uL = args.scalar("uL"); + double uR = args.scalar("uR"); + // PARAMETERS FOR EDGE VISCOSITY + int numDOFs = args.scalar("numDOFs"); + int NNZ = args.scalar("NNZ"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); + xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); + xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); + xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); + // C matrices + xt::pyarray& Cx = args.array("Cx"); + xt::pyarray& Cy = args.array("Cy"); + xt::pyarray& Cz = args.array("Cz"); + xt::pyarray& CTx = args.array("CTx"); + xt::pyarray& CTy = args.array("CTy"); + xt::pyarray& CTz = args.array("CTz"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); + int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); + // FOR FCT + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& fluxMatrix = args.array("fluxMatrix"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); + xt::pyarray& min_s_bc = args.array("min_s_bc"); + xt::pyarray& max_s_bc = args.array("max_s_bc"); + // AUX QUANTITIES OF INTEREST + xt::pyarray& quantDOFs = args.array("quantDOFs"); + xt::pyarray& sLow = args.array("sLow"); + xt::pyarray& sn = args.array("sn"); + + assert(a_rowptr.data()[nSpace] == nnz); + assert(a_rowptr.data()[nSpace] == nSpace); + //cek should this be read in? + double Ct_sge = 4.0; + + //loop over elements to compute volume integrals and load them into element and global residual + // + //eN is the element index + //eN_k is the quadrature point index for a scalar + //eN_k_nSpace is the quadrature point index for a vector + //eN_i is the element test function index + //eN_j is the element trial function index + //eN_k_j is the quadrature point index for a trial function + //eN_k_i is the quadrature point index for a trial function + for(int eN=0;eN& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); + xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); + xt::pyarray& globalJacobian = args.array("globalJacobian"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + assert(a_rowptr.data()[nSpace] == nnz); + assert(a_rowptr.data()[nSpace] == nSpace); + double Ct_sge = 4.0; + + // + //loop over elements to compute volume integrals and load them into the element Jacobians and global Jacobian + // + for(int eN=0;eN& bc_mask = args.array("bc_mask"); + int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern + int numDOFs = args.scalar("numDOFs"); //number of DOFs + double dt = args.scalar("dt"); + xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) + xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn + xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn + xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& limited_solution = args.array("limited_solution"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets + xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices + xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 + xt::pyarray& max_s_bc = args.array("max_s_bc"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int MONOLITHIC = args.scalar("MONOLITHIC"); + register double Rpos[numDOFs], Rneg[numDOFs]; + register double FluxCorrectionMatrix[NNZ]; + register double solL[numDOFs]; + register double sdot[numDOFs]; + ////////////////// + // LOOP in DOFs // + ////////////////// + int ij=0; + for (int i=0; i 0) ? 1. : 0.); + Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); + + //update ij + ij+=1; + //std::cout<<"sdoti error"<0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])) + * FluxCorrectionMatrix[ij]; + alpha_dot = fmin(1.0, beta_ij*fabs(alpha_fA)/MassMatrix.data()[ij]/fmax(1.0e-8,fabs(sdoti-sdotj))); + if (MONOLITHIC == 0) + { + ith_Limiter_times_FluxCorrectionMatrix += alpha_fA; + } + else + { + ith_Limiter_times_FluxCorrectionMatrix += alpha_fA + (LUMPED_MASS_MATRIX == 1 ? 0. : 1.)*dt*alpha_dot*MassMatrix.data()[ij]*(sdoti-sdotj); + } + //update ij + ij+=1; + } + limited_solution.data()[i] = solL[i] + 1./lumped_mass_matrix.data()[i]*ith_Limiter_times_FluxCorrectionMatrix*bc_mask[i]; + } + } + + void kth_FCT_step(arguments_dict& args) + { + int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern + int numDOFs = args.scalar("numDOFs"); //number of DOFs + int num_fct_iter = args.scalar("num_fct_iter"); + double dt = args.scalar("dt"); + xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) + xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn + xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn + xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& solLim = args.array("limited_solution"); + xt::pyarray& MC = args.array("MC"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& FluxMatrix = args.array("FluxMatrix"); + xt::pyarray& limitedFlux = args.array("limited_Flux"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets + xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices + xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 + xt::pyarray& max_s_bc = args.array("max_s_bc"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int MONOLITHIC = args.scalar("MONOLITHIC"); + register double Rpos[numDOFs], Rneg[numDOFs]; + int ij=0; + + ////////////////////////////////////////////////////// + // ********** COMPUTE LOW ORDER SOLUTION ********** // + ////////////////////////////////////////////////////// + if (num_fct_iter == 0) + { // No FCT for global bounds + for (int i=0; i 0) ? 1. : 0.); + // update ij + ij+=1; + } + // compute Q vectors + double mi = ML.data()[i]; + double solLimi = solLim.data()[i]; + double Qposi = mi*(maxi-solLimi); + // compute R vectors + Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + } + ij=0; + for (int i=0; i0 ? Rposi : Rpos[j]); + // compute limited flux + ith_Limiter_times_FluxCorrectionMatrix += Lij*Fluxij; + + // update limited flux + limitedFlux.data()[ij] = Lij*Fluxij; + + //update FluxMatrix + FluxMatrix.data()[ij] = Fluxij; + + //update ij + ij+=1; + } + //update limited solution + double mi = ML.data()[i]; + solLim.data()[i] += 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; + } + } + } + + // ***************************************** // + // ********** HIGH ORDER SOLUTION ********** // + // ***************************************** // + ij=0; + for (int i=0; i 0 ? 1. : 0.); + Pnegi += fij * (fij < 0 ? 1. : 0.); + //update ij + ij+=1; + } + // compute Q vectors // + double mi = ML.data()[i]; + double Qposi = mi*(maxi-solLim.data()[i]); + double Qnegi = mi*(mini-solLim.data()[i]); + // compute R vectors // + Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); + } + + // COMPUTE LIMITERS // + ij=0; + for (int i=0; i 0 ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j]); + // compute ith_limited_flux_correction + ith_limited_flux_correction += Lij*fij; + ij+=1; + } + double mi = ML.data()[i]; + solLim[i] += 1./mi*ith_limited_flux_correction; + } + } + + void calculateResidual_entropy_viscosity(arguments_dict& args) + { + xt::pyarray& globalJacobian = args.array("globalJacobian"); + double Theta = args.scalar("Theta"); + xt::pyarray& bc_mask = args.array("bc_mask"); + double dt = args.scalar("dt"); + xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + double sc_uref = args.scalar("sc_uref"); + double sc_alpha = args.scalar("sc_alpha"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& r_l2g = args.array("r_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + int degree_polynomial = args.scalar("degree_polynomial"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& u_dof_old = args.array("u_dof_old"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m = args.array("q_m"); + xt::pyarray& q_u = args.array("q_u"); + xt::pyarray& q_dV = args.array("q_dV"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + int offset_u = args.scalar("offset_u"); + int stride_u = args.scalar("stride_u"); + xt::pyarray& globalResidual = args.array("globalResidual"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& ebqe_phi = args.array("ebqe_phi"); + double epsFact = args.scalar("epsFact"); + xt::pyarray& ebqe_u = args.array("ebqe_u"); + xt::pyarray& ebqe_flux = args.array("ebqe_flux"); + // PARAMETERS FOR EDGE BASED STABILIZATION + double cE = args.scalar("cE"); + double cK = args.scalar("cK"); + // PARAMETERS FOR LOG BASED ENTROPY FUNCTION + double uL = args.scalar("uL"); + double uR = args.scalar("uR"); + // PARAMETERS FOR EDGE VISCOSITY + int numDOFs = args.scalar("numDOFs"); + int NNZ = args.scalar("NNZ"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); + xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); + xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); + xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); + // C matrices + xt::pyarray& Cx = args.array("Cx"); + xt::pyarray& Cy = args.array("Cy"); + xt::pyarray& Cz = args.array("Cz"); + xt::pyarray& CTx = args.array("CTx"); + xt::pyarray& CTy = args.array("CTy"); + xt::pyarray& CTz = args.array("CTz"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); + int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); + // FOR FCT + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& fluxMatrix = args.array("fluxMatrix"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); + xt::pyarray& min_s_bc = args.array("min_s_bc"); + xt::pyarray& max_s_bc = args.array("max_s_bc"); + // AUX QUANTITIES OF INTEREST + xt::pyarray& quantDOFs = args.array("quantDOFs"); + xt::pyarray& sLow = args.array("sLow"); + xt::pyarray& sn = args.array("sn"); + register double Rpos[numDOFs], Rneg[numDOFs]; + //register double FluxCorrectionMatrix[NNZ]; + // NOTE: This function follows a different (but equivalent) implementation of the smoothness based indicator than NCLS.h + // Allocate space for the transport matrices + // This is used for first order KUZMIN'S METHOD + register double TransportMatrix[NNZ],TransportMatrixConsistent[NNZ]; + register double TransportMatrixn[NNZ],TransportMatrixConsistentn[NNZ]; + std::valarray u_free_dof(numDOFs); + std::valarray u_free_dof_old(numDOFs); + std::valarray ML2(numDOFs); + for(int eN=0;eN= 0 && isFluxBoundary_u[ebNE_kb] != 1 ) //outflow. This is handled via the transport matrices. Then flux_ext=0 and dflux_ext!=0 */ + /* { */ + /* dflux_ext = flow; */ + /* flux_ext = 0; */ + /* // save external u */ + /* ebqe_u[ebNE_kb] = u_ext; */ + /* } */ + /* else // inflow. This is handled via the boundary integral. Then flux_ext!=0 and dflux_ext=0 */ + /* { */ + /* dflux_ext = 0; */ + /* // save external u */ + /* ebqe_u[ebNE_kb] = isDOFBoundary_u[ebNE_kb]*ebqe_bc_u_ext[ebNE_kb]+(1-isDOFBoundary_u[ebNE_kb])*u_ext; */ + /* if (isDOFBoundary_u[ebNE_kb] == 1) */ + /* flux_ext = ebqe_bc_u_ext[ebNE_kb]*flow; */ + /* else if (isFluxBoundary_u[ebNE_kb] == 1) */ + /* flux_ext = ebqe_bc_flux_u_ext[ebNE_kb]; */ + /* else */ + /* { */ + /* std::cout<<"warning: VOF open boundary with no external trace, setting to zero for inflow"<= 0.) + { + alpha_numerator_pos += alpha_num; + alpha_denominator_pos += alpha_num; + } + else + { + alpha_numerator_neg += alpha_num; + alpha_denominator_neg += fabs(alpha_num); + } + //update ij + ij+=1; + } + // scale g vector by lumped mass matrix + if (fabs(ML.data()[i] - ML2[i]) > 1.0e-16) + std::cout<<"ML "< 0.0) + // assert( (xi[I] - xj[I]) == delta_x_ij[offset*3+I]); + //gi_times_x += gi[I]*(xi[I]-xj[I]); + gi_times_x += gi[I]*delta_x_ij.data()[offset*3+I]; + } + // compute the positive and negative part of gi*(xi-xj) + SumPos += gi_times_x > 0 ? gi_times_x : 0; + SumNeg += gi_times_x < 0 ? gi_times_x : 0; + } + double sigmaPosi = fmin(1.,(fabs(SumNeg)+1E-15)/(SumPos+1E-15)); + double sigmaNegi = fmin(1.,(SumPos+1E-15)/(fabs(SumNeg)+1E-15)); + double alpha_numi = fabs(sigmaPosi*alpha_numerator_pos + sigmaNegi*alpha_numerator_neg); + double alpha_deni = sigmaPosi*alpha_denominator_pos + sigmaNegi*alpha_denominator_neg; + if (IS_BETAij_ONE == 1) + { + alpha_numi = fabs(alpha_numerator_pos + alpha_numerator_neg); + alpha_deni = alpha_denominator_pos + alpha_denominator_neg; + } + double alphai = alpha_numi/(alpha_deni+1E-15); + quantDOFs.data()[i] = alphai; + + if (POWER_SMOOTHNESS_INDICATOR==0) + psi[i] = 1.0; + else + psi[i] = std::pow(alphai,POWER_SMOOTHNESS_INDICATOR); //NOTE: they use alpha^2 in the paper + } + ///////////////////////////////////////////// + // ** LOOP IN DOFs FOR EDGE BASED TERMS ** // + ///////////////////////////////////////////// + ij=0; + for (int i=0; i Dissipation matrices as well. + double soli = u_free_dof[i]; // solution at time tn for the ith DOF + double solni = u_free_dof_old[i]; // solution at time tn for the ith DOF + for (int I=0;I mMax) + { + std::cout<<"mass out of bounds "< 0) ? 1. : 0.); + // Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); + // ij+=1; + // } + // double mi = ML[i]; + // double solni = u_dof_old[i]; + // double Qposi = mi*(maxi-solni); + // double Qnegi = mi*(mini-solni); + + //std::cout << Qposi << std::endl; + // Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + // Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); + + //if (Rpos[i] < 0) + //{ + // std::cout << mi << "\t" << maxi << "\t" << solni << std::endl; + // std::cout << Qposi << "\t" << Pposi << std::endl; + // std::cout << Rpos[i] << std::endl; + //abort(); + //} + //} + + //ij=0; + //for (int i=0; i 1.0 || Rposi < 0.0) + //std::cout << "Rposi: " << Rposi << std::endl; + //if (Rnegi > 1.0 || Rnegi < 0.0) + //std::cout << "Rnegi: " << Rnegi << std::endl; + + // LOOP OVER THE SPARSITY PATTERN (j-LOOP)// + // for (int offset=csrRowIndeces_DofLoops.data()[i]; + // offset0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])); + // //Lij=0.0; + // ith_Limiter_times_FluxCorrectionMatrix += Lij*FluxCorrectionMatrix[ij]; + // //update ij + // ij+=1; + // } + // double mi = ML[i]; + // double solni = u_dof_old[i]; + // globalResidual[i] = solni + 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; + //} + + } + + void invert(arguments_dict& args) + { + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + xt::pyarray& globalResidual = args.array("globalResidual"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + int numDOFs = args.scalar("numDOFs"); + for (int i=0; i mMax) + { + std::cout<<"mass out of bounds "<("dt"); + xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + //element boundary + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + //physics + int nElements_global = args.scalar("nElements_global"); + //new + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + //end new + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& r_l2g = args.array("r_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + int degree_polynomial = args.scalar("degree_polynomial"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); + xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); + xt::pyarray& globalJacobian = args.array("globalJacobian"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + //std::cout<<"ndjaco address "<(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + else if (nSpaceIn == 2) + return proteus::chooseAndAllocateDiscretization2D(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + else + { + assert(nSpaceIn == 3); + return proteus::chooseAndAllocateDiscretization(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + } + } +}//proteus +#endif diff --git a/richards_fct/richards/edit/Richards_abc.py b/richards_fct/richards/edit/Richards_abc.py new file mode 100644 index 0000000000..abc00527bf --- /dev/null +++ b/richards_fct/richards/edit/Richards_abc.py @@ -0,0 +1,1745 @@ +from __future__ import division +from builtins import range +from past.utils import old_div +import proteus +from .cRichards import * +import numpy as np +from proteus.Transport import OneLevelTransport +from proteus.Transport import TC_base, NonlinearEquation, logEvent, memory +from proteus.Transport import FluxBoundaryConditions, Comm, cfemIntegrals +from proteus.Transport import DOFBoundaryConditions, Quadrature +from proteus.mprans import cArgumentsDict +from proteus.LinearAlgebraTools import SparseMat +from proteus import TimeIntegration +from proteus.NonlinearSolvers import ExplicitLumpedMassMatrixForRichards + +class ThetaScheme(TimeIntegration.BackwardEuler): + def __init__(self,transport,integrateInterpolationPoints=False): + self.transport=transport + TimeIntegration.BackwardEuler.__init__(self,transport, integrateInterpolationPoints) + def updateTimeHistory(self,resetFromDOF=False): + TimeIntegration.BackwardEuler.updateTimeHistory(self,resetFromDOF) + self.transport.u_dof_old[:] = self.u +class RKEV(TimeIntegration.SSP): + from proteus import TimeIntegration + """ + Wrapper for SSPRK time integration using EV + + ... more to come ... + """ + + def __init__(self, transport, timeOrder=1, runCFL=0.1, integrateInterpolationPoints=False): + TimeIntegration.SSP.__init__(self, transport, integrateInterpolationPoints=integrateInterpolationPoints) + self.runCFL = runCFL + self.dtLast = None + self.isAdaptive = True + # About the cfl + assert transport.coefficients.STABILIZATION_TYPE > 0, "SSP method just works for edge based EV methods; i.e., STABILIZATION_TYPE>0" + assert hasattr(transport, 'edge_based_cfl'), "No edge based cfl defined" + self.cfl = transport.edge_based_cfl + # Stuff particular for SSP + self.timeOrder = timeOrder # order of approximation + self.nStages = timeOrder # number of stages total + self.lstage = 0 # last stage completed + # storage vectors + self.u_dof_last = {} + # per component stage values, list with array at each stage + self.u_dof_stage = {} + for ci in range(self.nc): + if ('m', ci) in transport.q: + self.u_dof_last[ci] = transport.u[ci].dof.copy() + self.u_dof_stage[ci] = [] + for k in range(self.nStages + 1): + self.u_dof_stage[ci].append(transport.u[ci].dof.copy()) + + # def set_dt(self, DTSET): + # self.dt = DTSET # don't update t + def choose_dt(self): + comm = Comm.get() + maxCFL = 1.0e-6 + maxCFL = max(maxCFL, comm.globalMax(self.cfl.max())) + self.dt = old_div(self.runCFL, maxCFL) + if self.dtLast is None: + self.dtLast = self.dt + self.t = self.tLast + self.dt + self.substeps = [self.t for i in range(self.nStages)] # Manuel is ignoring different time step levels for now + + def initialize_dt(self, t0, tOut, q): + """ + Modify self.dt + """ + self.tLast = t0 + self.choose_dt() + self.t = t0 + self.dt + + def setCoefficients(self): + """ + beta are all 1's here + mwf not used right now + """ + self.alpha = np.zeros((self.nStages, self.nStages), 'd') + self.dcoefs = np.zeros((self.nStages), 'd') + + def updateStage(self): + """ + Need to switch to use coefficients + """ + self.lstage += 1 + assert self.timeOrder in [1, 2, 3] + assert self.lstage > 0 and self.lstage <= self.timeOrder + if self.timeOrder == 3: + if self.lstage == 1: + logEvent("First stage of SSP33 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + # update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] + elif self.lstage == 2: + logEvent("Second stage of SSP33 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + self.u_dof_stage[ci][self.lstage] *= old_div(1., 4.) + self.u_dof_stage[ci][self.lstage] += 3. / 4. * self.u_dof_last[ci] + # Update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] + elif self.lstage == 3: + logEvent("Third stage of SSP33 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + self.u_dof_stage[ci][self.lstage] *= old_div(2.0, 3.0) + self.u_dof_stage[ci][self.lstage] += 1.0 / 3.0 * self.u_dof_last[ci] + # update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_last[ci] + # update solution to u[0].dof + self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] + elif self.timeOrder == 2: + if self.lstage == 1: + logEvent("First stage of SSP22 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + # Update u_dof_old + self.transport.u_dof_old[:] = self.transport.u[ci].dof + elif self.lstage == 2: + logEvent("Second stage of SSP22 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + self.u_dof_stage[ci][self.lstage][:] *= old_div(1., 2.) + self.u_dof_stage[ci][self.lstage][:] += 1. / 2. * self.u_dof_last[ci] + # update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_last[ci] + # update solution to u[0].dof + self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] + else: + assert self.timeOrder == 1 + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof[:] + self.transport.u_dof_old[:] = self.transport.u[ci].dof + + def initializeTimeHistory(self, resetFromDOF=True): + """ + Push necessary information into time history arrays + """ + for ci in range(self.nc): + self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] + for k in range(self.nStages): + self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] + + def updateTimeHistory(self, resetFromDOF=False): + """ + assumes successful step has been taken + """ + + self.t = self.tLast + self.dt + for ci in range(self.nc): + self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] + for k in range(self.nStages): + self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] + self.lstage = 0 + self.dtLast = self.dt + self.tLast = self.t + + def generateSubsteps(self, tList): + """ + create list of substeps over time values given in tList. These correspond to stages + """ + self.substeps = [] + tLast = self.tLast + for t in tList: + dttmp = t - tLast + self.substeps.extend([tLast + dttmp for i in range(self.nStages)]) + tLast = t + + def resetOrder(self, order): + """ + initialize data structures for stage updges + """ + self.timeOrder = order # order of approximation + self.nStages = order # number of stages total + self.lstage = 0 # last stage completed + # storage vectors + # per component stage values, list with array at each stage + self.u_dof_stage = {} + for ci in range(self.nc): + if ('m', ci) in self.transport.q: + self.u_dof_stage[ci] = [] + for k in range(self.nStages + 1): + self.u_dof_stage[ci].append(self.transport.u[ci].dof.copy()) + self.substeps = [self.t for i in range(self.nStages)] + + def setFromOptions(self, nOptions): + """ + allow classes to set various numerical parameters + """ + if 'runCFL' in dir(nOptions): + self.runCFL = nOptions.runCFL + flags = ['timeOrder'] + for flag in flags: + if flag in dir(nOptions): + val = getattr(nOptions, flag) + setattr(self, flag, val) + if flag == 'timeOrder': + self.resetOrder(self.timeOrder) + +class Coefficients(proteus.TransportCoefficients.TC_base): + """ + version of Re where element material type id's used in evals + """ + from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2 + from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchten_sd_het + def __init__(self, + nd, + Ksw_types, + vgm_n_types, + vgm_alpha_types, + thetaR_types, + thetaSR_types, + gravity, + density, + beta, + diagonal_conductivity=True, + getSeepageFace=None, + # FOR EDGE BASED EV + STABILIZATION_TYPE=0, + ENTROPY_TYPE=2, # logarithmic + LUMPED_MASS_MATRIX=False, + MONOLITHIC=True, + FCT=False, + forceStrongBoundaryConditions=False, + num_fct_iter=1, + # FOR ENTROPY VISCOSITY + cE=1.0, + uL=0.0, + uR=1.0, + # FOR ARTIFICIAL COMPRESSION + cK=1.0, + # OUTPUT quantDOFs + outputQuantDOFs=False): + variableNames=['pressure_head'] + nc=1 + mass={0:{0:'nonlinear'}} + advection={0:{0:'nonlinear'}} + diffusion={0:{0:{0:'nonlinear'}}} + potential={0:{0:'u'}} + reaction={0:{0:'linear'}} + hamiltonian={} + self.getSeepageFace=getSeepageFace + self.gravity=gravity + self.rho = density + self.beta=beta + self.vgm_n_types = vgm_n_types + self.vgm_alpha_types = vgm_alpha_types + self.thetaR_types = thetaR_types + self.thetaSR_types = thetaSR_types + self.elementMaterialTypes = None + self.exteriorElementBoundaryTypes = None + self.materialTypes_q = None + self.materialTypes_ebq = None + self.materialTypes_ebqe = None + self.nd = nd + self.nMaterialTypes = len(thetaR_types) + self.q = {}; self.ebqe = {}; self.ebq = {}; self.ebq_global={} + #try to allow some flexibility in input of permeability/conductivity tensor + self.diagonal_conductivity = diagonal_conductivity + self.Ksw_types_in = Ksw_types + if self.diagonal_conductivity: + sparseDiffusionTensors = {(0,0):(np.arange(self.nd+1,dtype='i'), + np.arange(self.nd,dtype='i'))} + + assert len(Ksw_types.shape) in [1,2], "if diagonal conductivity true then Ksw_types scalar or vector of diagonal entries" + #allow scalar input Ks + if len(Ksw_types.shape)==1: + self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd),'d') + for I in range(self.nd): + self.Ksw_types[:,I] = Ksw_types + else: + self.Ksw_types = Ksw_types + else: #full + sparseDiffusionTensors = {(0,0):(np.arange(self.nd**2+1,step=self.nd,dtype='i'), + np.array([list(range(self.nd)) for row in range(self.nd)],dtype='i'))} + assert len(Ksw_types.shape) in [1,2], "if full tensor conductivity true then Ksw_types scalar or 'flattened' row-major representation of entries" + if len(Ksw_types.shape)==1: + self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd**2),'d') + for I in range(self.nd): + self.Ksw_types[:,I*self.nd+I] = Ksw_types + else: + assert Ksw_types.shape[1] == self.nd**2 + self.Ksw_types = Ksw_types + # EDGE BASED (AND ENTROPY) VISCOSITY + self.LUMPED_MASS_MATRIX = LUMPED_MASS_MATRIX + self.MONOLITHIC = MONOLITHIC + self.STABILIZATION_TYPE = STABILIZATION_TYPE + self.ENTROPY_TYPE = ENTROPY_TYPE + self.FCT = FCT + self.num_fct_iter=num_fct_iter + self.uL = uL + self.uR = uR + self.cK = cK + self.forceStrongConditions = forceStrongBoundaryConditions + self.cE = cE + self.outputQuantDOFs = outputQuantDOFs + TC_base.__init__(self, + nc, + mass, + advection, + diffusion, + potential, + reaction, + hamiltonian, + variableNames, + sparseDiffusionTensors = sparseDiffusionTensors, + useSparseDiffusion = True) + + def initializeMesh(self,mesh): + from proteus.SubsurfaceTransportCoefficients import BlockHeterogeneousCoefficients + self.elementMaterialTypes,self.exteriorElementBoundaryTypes,self.elementBoundaryTypes = BlockHeterogeneousCoefficients(mesh).initializeMaterialTypes() + #want element boundary material types for evaluating heterogeneity + #not boundary conditions + self.isSeepageFace = np.zeros((mesh.nExteriorElementBoundaries_global),'i') + if self.getSeepageFace != None: + for ebNE in range(mesh.nExteriorElementBoundaries_global): + #mwf missing ebNE-->ebN? + ebN = mesh.exteriorElementBoundariesArray[ebNE] + #print "eb flag",mesh.elementBoundaryMaterialTypes[ebN] + #print self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) + self.isSeepageFace[ebNE] = self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) + #print self.isSeepageFace + def initializeElementQuadrature(self,t,cq): + self.materialTypes_q = self.elementMaterialTypes + self.q_shape = cq[('u',0)].shape +# cq['Ks'] = np.zeros(self.q_shape,'d') +# for k in range(self.q_shape[1]): +# cq['Ks'][:,k] = self.Ksw_types[self.elementMaterialTypes,0] + self.q[('vol_frac',0)] = np.zeros(self.q_shape,'d') + def initializeElementBoundaryQuadrature(self,t,cebq,cebq_global): + self.materialTypes_ebq = np.zeros(cebq[('u',0)].shape[0:2],'i') + self.ebq_shape = cebq[('u',0)].shape + for ebN_local in range(self.ebq_shape[1]): + self.materialTypes_ebq[:,ebN_local] = self.elementMaterialTypes + self.ebq[('vol_frac',0)] = np.zeros(self.ebq_shape,'d') + + def initializeGlobalExteriorElementBoundaryQuadrature(self,t,cebqe): + self.materialTypes_ebqe = self.exteriorElementBoundaryTypes + self.ebqe_shape = cebqe[('u',0)].shape + self.ebqe[('vol_frac',0)] = np.zeros(self.ebqe_shape,'d') + # + def evaluate(self,t,c): + if c[('u',0)].shape == self.q_shape: + materialTypes = self.materialTypes_q + vol_frac = self.q[('vol_frac',0)] + elif c[('u',0)].shape == self.ebqe_shape: + materialTypes = self.materialTypes_ebqe + vol_frac = self.ebqe[('vol_frac',0)] + elif c[('u',0)].shape == self.ebq_shape: + materialTypes = self.materialTypes_ebq + vol_frac = self.ebq[('vol_frac',0)] + else: + assert False, "no materialType found to match c[('u',0)].shape= %s " % c[('u',0)].shape + self.conservativeHeadRichardsMualemVanGenuchten_sd_het(self.sdInfo[(0,0)][0], + self.sdInfo[(0,0)][1], + materialTypes, + self.rho, + self.beta, + self.gravity, + self.vgm_alpha_types, + self.vgm_n_types, + self.thetaR_types, + self.thetaSR_types, + self.Ksw_types, + c[('u',0)], + c[('m',0)], + c[('dm',0,0)], + c[('f',0)], + c[('df',0,0)], + c[('a',0,0)], + c[('da',0,0,0)], + vol_frac) + # print "Picard---------------------------------------------------------------" + # c[('df',0,0)][:] = 0.0 + # c[('da',0,0,0)][:] = 0.0 +# self.conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2(materialTypes, +# self.rho, +# self.beta, +# self.gravity, +# self.vgm_alpha_types, +# self.vgm_n_types, +# self.thetaR_types, +# self.thetaSR_types, +# self.Ksw_types, +# c[('u',0)], +# c[('m',0)], +# c[('dm',0,0)], +# c[('f',0)], +# c[('df',0,0)], +# c[('a',0,0)], +# c[('da',0,0,0)]) + #mwf debug + if (np.isnan(c[('da',0,0,0)]).any() or + np.isnan(c[('a',0,0)]).any() or + np.isnan(c[('df',0,0)]).any() or + np.isnan(c[('f',0)]).any() or + np.isnan(c[('u',0)]).any() or + np.isnan(c[('m',0)]).any() or + np.isnan(c[('dm',0,0)]).any()): + import pdb + pdb.set_trace() + +# #mwf debug +# if c[('u',0)].shape == self.q_shape: +# c[('visPerm',0)]=c[('a',0,0)][:,:,0,0] + +class LevelModel(proteus.Transport.OneLevelTransport): + nCalls=0 + def __init__(self, + uDict, + phiDict, + testSpaceDict, + matType, + dofBoundaryConditionsDict, + dofBoundaryConditionsSetterDict, + coefficients, + elementQuadrature, + elementBoundaryQuadrature, + fluxBoundaryConditionsDict=None, + advectiveFluxBoundaryConditionsSetterDict=None, + diffusiveFluxBoundaryConditionsSetterDictDict=None, + stressTraceBoundaryConditionsSetterDict=None, + stabilization=None, + shockCapturing=None, + conservativeFluxDict=None, + numericalFluxType=None, + TimeIntegrationClass=None, + massLumping=False, + reactionLumping=False, + options=None, + name='defaultName', + reuse_trial_and_test_quadrature=True, + sd = True, + movingDomain=False, + bdyNullSpace=False): + self.bdyNullSpace=bdyNullSpace + # + #set the objects describing the method and boundary conditions + # + self.movingDomain=movingDomain + self.tLast_mesh=None + # + self.name=name + self.sd=sd + self.Hess=False + self.lowmem=True + self.timeTerm=True#allow turning off the time derivative + #self.lowmem=False + self.testIsTrial=True + self.phiTrialIsTrial=True + self.u = uDict + self.ua = {}#analytical solutions + self.phi = phiDict + self.dphi={} + self.matType = matType + #mwf try to reuse test and trial information across components if spaces are the same + self.reuse_test_trial_quadrature = reuse_trial_and_test_quadrature#True#False + if self.reuse_test_trial_quadrature: + for ci in range(1,coefficients.nc): + assert self.u[ci].femSpace.__class__.__name__ == self.u[0].femSpace.__class__.__name__, "to reuse_test_trial_quad all femSpaces must be the same!" + self.u_dof_old = None + ## Simplicial Mesh + self.mesh = self.u[0].femSpace.mesh #assume the same mesh for all components for now + self.testSpace = testSpaceDict + self.dirichletConditions = dofBoundaryConditionsDict + self.dirichletNodeSetList=None #explicit Dirichlet conditions for now, no Dirichlet BC constraints + self.coefficients = coefficients + self.coefficients.initializeMesh(self.mesh) + self.nc = self.coefficients.nc + self.stabilization = stabilization + self.shockCapturing = shockCapturing + self.conservativeFlux = conservativeFluxDict #no velocity post-processing for now + self.fluxBoundaryConditions=fluxBoundaryConditionsDict + self.advectiveFluxBoundaryConditionsSetterDict=advectiveFluxBoundaryConditionsSetterDict + self.diffusiveFluxBoundaryConditionsSetterDictDict = diffusiveFluxBoundaryConditionsSetterDictDict + #determine whether the stabilization term is nonlinear + self.stabilizationIsNonlinear = False + #cek come back + if self.stabilization != None: + for ci in range(self.nc): + if ci in coefficients.mass: + for flag in list(coefficients.mass[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.advection: + for flag in list(coefficients.advection[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.diffusion: + for diffusionDict in list(coefficients.diffusion[ci].values()): + for flag in list(diffusionDict.values()): + if flag != 'constant': + self.stabilizationIsNonlinear=True + if ci in coefficients.potential: + for flag in list(coefficients.potential[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.reaction: + for flag in list(coefficients.reaction[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.hamiltonian: + for flag in list(coefficients.hamiltonian[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + #determine if we need element boundary storage + self.elementBoundaryIntegrals = {} + for ci in range(self.nc): + self.elementBoundaryIntegrals[ci] = ((self.conservativeFlux != None) or + (numericalFluxType != None) or + (self.fluxBoundaryConditions[ci] == 'outFlow') or + (self.fluxBoundaryConditions[ci] == 'mixedFlow') or + (self.fluxBoundaryConditions[ci] == 'setFlow')) + # + #calculate some dimensions + # + self.nSpace_global = self.u[0].femSpace.nSpace_global #assume same space dim for all variables + self.nDOF_trial_element = [u_j.femSpace.max_nDOF_element for u_j in list(self.u.values())] + self.nDOF_phi_trial_element = [phi_k.femSpace.max_nDOF_element for phi_k in list(self.phi.values())] + self.n_phi_ip_element = [phi_k.femSpace.referenceFiniteElement.interpolationConditions.nQuadraturePoints for phi_k in list(self.phi.values())] + self.nDOF_test_element = [femSpace.max_nDOF_element for femSpace in list(self.testSpace.values())] + self.nFreeDOF_global = [dc.nFreeDOF_global for dc in list(self.dirichletConditions.values())] + self.nVDOF_element = sum(self.nDOF_trial_element) + self.nFreeVDOF_global = sum(self.nFreeDOF_global) + # + NonlinearEquation.__init__(self,self.nFreeVDOF_global) + # + #build the quadrature point dictionaries from the input (this + #is just for convenience so that the input doesn't have to be + #complete) + # + elementQuadratureDict={} + elemQuadIsDict = isinstance(elementQuadrature,dict) + if elemQuadIsDict: #set terms manually + for I in self.coefficients.elementIntegralKeys: + if I in elementQuadrature: + elementQuadratureDict[I] = elementQuadrature[I] + else: + elementQuadratureDict[I] = elementQuadrature['default'] + else: + for I in self.coefficients.elementIntegralKeys: + elementQuadratureDict[I] = elementQuadrature + if self.stabilization != None: + for I in self.coefficients.elementIntegralKeys: + if elemQuadIsDict: + if I in elementQuadrature: + elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature[I] + else: + elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature['default'] + else: + elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature + if self.shockCapturing != None: + for ci in self.shockCapturing.components: + if elemQuadIsDict: + if ('numDiff',ci,ci) in elementQuadrature: + elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature[('numDiff',ci,ci)] + else: + elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature['default'] + else: + elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature + if massLumping: + for ci in list(self.coefficients.mass.keys()): + elementQuadratureDict[('m',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + for I in self.coefficients.elementIntegralKeys: + elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + if reactionLumping: + for ci in list(self.coefficients.mass.keys()): + elementQuadratureDict[('r',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + for I in self.coefficients.elementIntegralKeys: + elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + elementBoundaryQuadratureDict={} + if isinstance(elementBoundaryQuadrature,dict): #set terms manually + for I in self.coefficients.elementBoundaryIntegralKeys: + if I in elementBoundaryQuadrature: + elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature[I] + else: + elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature['default'] + else: + for I in self.coefficients.elementBoundaryIntegralKeys: + elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature + # + # find the union of all element quadrature points and + # build a quadrature rule for each integral that has a + # weight at each point in the union + #mwf include tag telling me which indices are which quadrature rule? + (self.elementQuadraturePoints,self.elementQuadratureWeights, + self.elementQuadratureRuleIndeces) = Quadrature.buildUnion(elementQuadratureDict) + self.nQuadraturePoints_element = self.elementQuadraturePoints.shape[0] + self.nQuadraturePoints_global = self.nQuadraturePoints_element*self.mesh.nElements_global + # + #Repeat the same thing for the element boundary quadrature + # + (self.elementBoundaryQuadraturePoints, + self.elementBoundaryQuadratureWeights, + self.elementBoundaryQuadratureRuleIndeces) = Quadrature.buildUnion(elementBoundaryQuadratureDict) + self.nElementBoundaryQuadraturePoints_elementBoundary = self.elementBoundaryQuadraturePoints.shape[0] + self.nElementBoundaryQuadraturePoints_global = (self.mesh.nElements_global* + self.mesh.nElementBoundaries_element* + self.nElementBoundaryQuadraturePoints_elementBoundary) +# if isinstance(self.u[0].femSpace,C0_AffineLinearOnSimplexWithNodalBasis): +# print self.nQuadraturePoints_element +# if self.nSpace_global == 3: +# assert(self.nQuadraturePoints_element == 5) +# elif self.nSpace_global == 2: +# assert(self.nQuadraturePoints_element == 6) +# elif self.nSpace_global == 1: +# assert(self.nQuadraturePoints_element == 3) +# +# print self.nElementBoundaryQuadraturePoints_elementBoundary +# if self.nSpace_global == 3: +# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) +# elif self.nSpace_global == 2: +# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) +# elif self.nSpace_global == 1: +# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 1) + + # + #storage dictionaries + self.scalars_element = set() + # + #simplified allocations for test==trial and also check if space is mixed or not + # + self.q={} + self.ebq={} + self.ebq_global={} + self.ebqe={} + self.phi_ip={} + self.edge_based_cfl = np.zeros(self.u[0].dof.shape)+100 + #mesh + #self.q['x'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,3),'d') + self.q[('dV_u', 0)] = (old_div(1.0, self.mesh.nElements_global)) * np.ones((self.mesh.nElements_global, self.nQuadraturePoints_element), 'd') + self.ebqe['x'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,3),'d') + self.q[('u',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') + self.q[('grad(u)',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') + self.q['velocity'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') + self.q[('m',0)] = self.q[('u',0)].copy() + self.q[('mt',0)] = self.q[('u',0)].copy() + self.q[('m_last',0)] = self.q[('u',0)].copy() + self.q[('m_tmp',0)] = self.q[('u',0)].copy() + self.q[('cfl',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') + self.q[('numDiff',0,0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') + self.ebqe[('u',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.ebqe[('grad(u)',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') + self.ebqe['velocity'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') + self.ebqe[('advectiveFlux_bc_flag',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'i') + self.ebqe[('advectiveFlux_bc',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.ebqe[('advectiveFlux',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.ebqe[('penalty')] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.points_elementBoundaryQuadrature= set() + self.scalars_elementBoundaryQuadrature= set([('u',ci) for ci in range(self.nc)]) + self.vectors_elementBoundaryQuadrature= set() + self.tensors_elementBoundaryQuadrature= set() + self.inflowBoundaryBC = {} + self.inflowBoundaryBC_values = {} + self.inflowFlux = {} + for cj in range(self.nc): + self.inflowBoundaryBC[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,),'i') + self.inflowBoundaryBC_values[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nDOF_trial_element[cj]),'d') + self.inflowFlux[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.internalNodes = set(range(self.mesh.nNodes_global)) + #identify the internal nodes this is ought to be in mesh + ##\todo move this to mesh + for ebNE in range(self.mesh.nExteriorElementBoundaries_global): + ebN = self.mesh.exteriorElementBoundariesArray[ebNE] + eN_global = self.mesh.elementBoundaryElementsArray[ebN,0] + ebN_element = self.mesh.elementBoundaryLocalElementBoundariesArray[ebN,0] + for i in range(self.mesh.nNodes_element): + if i != ebN_element: + I = self.mesh.elementNodesArray[eN_global,i] + self.internalNodes -= set([I]) + self.nNodes_internal = len(self.internalNodes) + self.internalNodesArray=np.zeros((self.nNodes_internal,),'i') + for nI,n in enumerate(self.internalNodes): + self.internalNodesArray[nI]=n + # + del self.internalNodes + self.internalNodes = None + logEvent("Updating local to global mappings",2) + self.updateLocal2Global() + logEvent("Building time integration object",2) + logEvent(memory("inflowBC, internalNodes,updateLocal2Global","OneLevelTransport"),level=4) + #mwf for interpolating subgrid error for gradients etc + if self.stabilization and self.stabilization.usesGradientStabilization: + self.timeIntegration = TimeIntegrationClass(self,integrateInterpolationPoints=True) + else: + self.timeIntegration = TimeIntegrationClass(self) + + if options != None: + self.timeIntegration.setFromOptions(options) + logEvent(memory("TimeIntegration","OneLevelTransport"),level=4) + logEvent("Calculating numerical quadrature formulas",2) + self.calculateQuadrature() + #lay out components/equations contiguously for now + self.offset = [0] + for ci in range(1,self.nc): + self.offset += [self.offset[ci-1]+self.nFreeDOF_global[ci-1]] + self.stride = [1 for ci in range(self.nc)] + #use contiguous layout of components for parallel, requires weak DBC's + # mql. Some ASSERTS to restrict the combination of the methods + if self.coefficients.STABILIZATION_TYPE > 0: + pass + #assert self.timeIntegration.isSSP == True, "If STABILIZATION_TYPE>0, use RKEV timeIntegration within VOF model" + #cond = 'levelNonlinearSolver' in dir(options) and (options.levelNonlinearSolver == + # ExplicitLumpedMassMatrixForRichards or options.levelNonlinearSolver == ExplicitConsistentMassMatrixForRichards) + #assert cond, "If STABILIZATION_TYPE>0, use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards or ExplicitConsistentMassMatrixForRichards" + try: + if 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards: + assert self.coefficients.LUMPED_MASS_MATRIX, "If levelNonlinearSolver=ExplicitLumpedMassMatrix, use LUMPED_MASS_MATRIX=True" + except: + pass + if self.coefficients.LUMPED_MASS_MATRIX == True: + cond = self.coefficients.STABILIZATION_TYPE == 2 + assert cond, "Use lumped mass matrix just with: STABILIZATION_TYPE=2 (smoothness based stab.)" + cond = 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards + assert cond, "Use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards when the mass matrix is lumped" + if self.coefficients.FCT == True: + cond = self.coefficients.STABILIZATION_TYPE > 0, "Use FCT just with STABILIZATION_TYPE>0; i.e., edge based stabilization" + # END OF ASSERTS + + # cek adding empty data member for low order numerical viscosity structures here for now + self.ML = None # lumped mass matrix + self.MC_global = None # consistent mass matrix + self.cterm_global = None + self.cterm_transpose_global = None + # dL_global and dC_global are not the full matrices but just the CSR arrays containing the non zero entries + self.residualComputed=False #TMP + self.dLow= None + self.fluxMatrix = None + self.uDotLow = None + self.uLow = None + self.dt_times_dC_minus_dL = None + self.min_s_bc = None + self.max_s_bc = None + # Aux quantity at DOFs to be filled by optimized code (MQL) + self.quantDOFs = np.zeros(self.u[0].dof.shape, 'd') + self.sLow = np.zeros(self.u[0].dof.shape, 'd') + self.sHigh = np.zeros(self.u[0].dof.shape, 'd') + self.sn = np.zeros(self.u[0].dof.shape, 'd') + comm = Comm.get() + self.comm=comm + if comm.size() > 1: + assert numericalFluxType != None and numericalFluxType.useWeakDirichletConditions,"You must use a numerical flux to apply weak boundary conditions for parallel runs" + self.offset = [0] + for ci in range(1,self.nc): + self.offset += [ci] + self.stride = [self.nc for ci in range(self.nc)] + # + logEvent(memory("stride+offset","OneLevelTransport"),level=4) + if numericalFluxType != None: + if options is None or options.periodicDirichletConditions is None: + self.numericalFlux = numericalFluxType(self, + dofBoundaryConditionsSetterDict, + advectiveFluxBoundaryConditionsSetterDict, + diffusiveFluxBoundaryConditionsSetterDictDict) + else: + self.numericalFlux = numericalFluxType(self, + dofBoundaryConditionsSetterDict, + advectiveFluxBoundaryConditionsSetterDict, + diffusiveFluxBoundaryConditionsSetterDictDict, + options.periodicDirichletConditions) + else: + self.numericalFlux = None + #set penalty terms + #cek todo move into numerical flux initialization + if 'penalty' in self.ebq_global: + for ebN in range(self.mesh.nElementBoundaries_global): + for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): + self.ebq_global['penalty'][ebN,k] = old_div(self.numericalFlux.penalty_constant,(self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power)) + #penalty term + #cek move to Numerical flux initialization + if 'penalty' in self.ebqe: + for ebNE in range(self.mesh.nExteriorElementBoundaries_global): + ebN = self.mesh.exteriorElementBoundariesArray[ebNE] + for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): + self.ebqe['penalty'][ebNE,k] = old_div(self.numericalFlux.penalty_constant,self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power) + logEvent(memory("numericalFlux","OneLevelTransport"),level=4) + self.elementEffectiveDiametersArray = self.mesh.elementInnerDiametersArray + #use post processing tools to get conservative fluxes, None by default + from proteus import PostProcessingTools + self.velocityPostProcessor = PostProcessingTools.VelocityPostProcessingChooser(self) + logEvent(memory("velocity postprocessor","OneLevelTransport"),level=4) + #helper for writing out data storage + from proteus import Archiver + self.elementQuadratureDictionaryWriter = Archiver.XdmfWriter() + self.elementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() + self.exteriorElementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() + #TODO get rid of this + for ci,fbcObject in list(self.fluxBoundaryConditionsObjectsDict.items()): + self.ebqe[('advectiveFlux_bc_flag',ci)] = np.zeros(self.ebqe[('advectiveFlux_bc',ci)].shape,'i') + for t,g in list(fbcObject.advectiveFluxBoundaryConditionsDict.items()): + if ci in self.coefficients.advection: + self.ebqe[('advectiveFlux_bc',ci)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) + self.ebqe[('advectiveFlux_bc_flag',ci)][t[0],t[1]] = 1 + + if hasattr(self.numericalFlux,'setDirichletValues'): + self.numericalFlux.setDirichletValues(self.ebqe) + if not hasattr(self.numericalFlux,'isDOFBoundary'): + self.numericalFlux.isDOFBoundary = {0:np.zeros(self.ebqe[('u',0)].shape,'i')} + if not hasattr(self.numericalFlux,'ebqe'): + self.numericalFlux.ebqe = {('u',0):np.zeros(self.ebqe[('u',0)].shape,'d')} + #TODO how to handle redistancing calls for calculateCoefficients,calculateElementResidual etc + self.globalResidualDummy = None + compKernelFlag=0 + self.delta_x_ij=None + self.richards = cRichards_base(self.nSpace_global, + self.nQuadraturePoints_element, + self.u[0].femSpace.elementMaps.localFunctionSpace.dim, + self.u[0].femSpace.referenceFiniteElement.localFunctionSpace.dim, + self.testSpace[0].referenceFiniteElement.localFunctionSpace.dim, + self.nElementBoundaryQuadraturePoints_elementBoundary, + compKernelFlag) + if self.movingDomain: + self.MOVING_DOMAIN=1.0 + else: + self.MOVING_DOMAIN=0.0 + #cek hack + self.movingDomain=False + self.MOVING_DOMAIN=0.0 + if self.mesh.nodeVelocityArray is None: + self.mesh.nodeVelocityArray = np.zeros(self.mesh.nodeArray.shape,'d') + self.forceStrongConditions=self.coefficients.forceStrongConditions + self.dirichletConditionsForceDOF = {} + if self.forceStrongConditions: + for cj in range(self.nc): + self.dirichletConditionsForceDOF[cj] = DOFBoundaryConditions(self.u[cj].femSpace,dofBoundaryConditionsSetterDict[cj],weakDirichletConditions=False) + def FCTStep(self): + import pdb + rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() + limited_solution = np.zeros((len(rowptr) - 1),'d') + #self.u_free_dof_stage_0_l = np.zeros((len(rowptr) - 1),'d') + #self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage], # soln + #fromFreeToGlobal=0 + #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + # self.offset[0], + # self.stride[0], + # self.dirichletConditions[0].global2freeGlobal_global_dofs, + # self.dirichletConditions[0].global2freeGlobal_free_dofs, + # self.u_free_dof_stage_0_l, + # self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage]) + argsDict = cArgumentsDict.ArgumentsDict() + argsDict["bc_mask"] = self.bc_mask + argsDict["NNZ"] = self.nnz + argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs + argsDict["dt"] = self.timeIntegration.dt + argsDict["lumped_mass_matrix"] = self.ML + argsDict["soln"] = self.sn + argsDict["pn"] = self.u[0].dof + argsDict["solH"] = self.sHigh + argsDict["uLow"] = self.sLow + argsDict["uDotLow"] = self.uDotLow + argsDict["limited_solution"] = limited_solution + argsDict["csrRowIndeces_DofLoops"] = rowptr + argsDict["csrColumnOffsets_DofLoops"] = colind + argsDict["MassMatrix"] = MassMatrix + argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL + argsDict["min_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0]) #cek hack just set from physical bounds + argsDict["max_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0] + self.coefficients.thetaSR_types[0]) #cek hack + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["MONOLITHIC"] =0#cek hack self.coefficients.MONOLITHIC + #pdb.set_trace() + self.richards.FCTStep(argsDict) + + # self.nnz, # number of non zero entries + # len(rowptr) - 1, # number of DOFs + # self.timeIntegration.dt, + # self.ML, # Lumped mass matrix + # self.sn, + # self.u_dof_old, + # self.sHigh, # high order solution + # self.sLow, + # limited_solution, + # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) + # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) + # MassMatrix, + # self.dt_times_dC_minus_dL, + # self.min_s_bc, + # self.max_s_bc, + # self.coefficients.LUMPED_MASS_MATRIX, + # self.coefficients.MONOLITHIC) + old_dof = self.u[0].dof.copy() + self.invert(limited_solution, self.u[0].dof) + self.timeIntegration.u[:] = self.u[0].dof + #fromFreeToGlobal=1 #direction copying + #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + # self.offset[0], + # self.stride[0], + # self.dirichletConditions[0].global2freeGlobal_global_dofs, + # self.dirichletConditions[0].global2freeGlobal_free_dofs, + # self.u[0].dof, + # limited_solution) + def kth_FCT_step(self): + #import pdb + #pdb.set_trace() + rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() + limitedFlux = np.zeros(self.nnz) + limited_solution = np.zeros((len(rowptr) - 1),'d') + #limited_solution[:] = self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage] + fromFreeToGlobal=0 #direction copying + cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + self.offset[0], + self.stride[0], + self.dirichletConditions[0].global2freeGlobal_global_dofs, + self.dirichletConditions[0].global2freeGlobal_free_dofs, + limited_solution, + self.timeintegration.u_dof_stage[0][self.timeIntegration.lstage]) + + self.richards.kth_FCT_step( + self.timeIntegration.dt, + self.coefficients.num_fct_iter, + self.nnz, # number of non zero entries + len(rowptr) - 1, # number of DOFs + MassMatrix, + self.ML, # Lumped mass matrix + self.u_dof_old, + limited_solution, + self.uDotLow, + self.uLow, + self.dLow, + self.fluxMatrix, + limitedFlux, + rowptr, + colind) + + self.timeIntegration.u[:] = limited_solution + #self.u[0].dof[:] = limited_solution + fromFreeToGlobal=1 #direction copying + cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + self.offset[0], + self.stride[0], + self.dirichletConditions[0].global2freeGlobal_global_dofs, + self.dirichletConditions[0].global2freeGlobal_free_dofs, + self.u[0].dof, + limited_solution) + def calculateCoefficients(self): + pass + def calculateElementResidual(self): + if self.globalResidualDummy != None: + self.getResidual(self.u[0].dof,self.globalResidualDummy) + def getResidual(self,u,r): + import pdb + import copy + """ + Calculate the element residuals and add in to the global residual + """ + cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, + self.jacobian) + if self.u_dof_old is None: + # Pass initial condition to u_dof_old + self.u_dof_old = np.copy(self.u[0].dof) + rowptr, colind, nzval = self.jacobian.getCSRrepresentation() + nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix + r.fill(0.0) + ######################## + ### COMPUTE C MATRIX ### + ######################## + if self.cterm_global is None: + # since we only need cterm_global to persist, we can drop the other self.'s + self.cterm = {} + self.cterm_a = {} + self.cterm_global = {} + self.cterm_transpose = {} + self.cterm_a_transpose = {} + self.cterm_global_transpose = {} + rowptr, colind, nzval = self.jacobian.getCSRrepresentation() + nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix + di = self.q[('grad(u)', 0)].copy() # direction of derivative + # JACOBIANS (FOR ELEMENT TRANSFORMATION) + self.q[('J')] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nSpace_global, + self.nSpace_global), + 'd') + self.q[('inverse(J)')] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nSpace_global, + self.nSpace_global), + 'd') + self.q[('det(J)')] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element), + 'd') + self.u[0].femSpace.elementMaps.getJacobianValues(self.elementQuadraturePoints, + self.q['J'], + self.q['inverse(J)'], + self.q['det(J)']) + self.q['abs(det(J))'] = np.abs(self.q['det(J)']) + # SHAPE FUNCTIONS + self.q[('w', 0)] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nDOF_test_element[0]), + 'd') + self.q[('w*dV_m', 0)] = self.q[('w', 0)].copy() + self.u[0].femSpace.getBasisValues(self.elementQuadraturePoints, self.q[('w', 0)]) + cfemIntegrals.calculateWeightedShape(self.elementQuadratureWeights[('u', 0)], + self.q['abs(det(J))'], + self.q[('w', 0)], + self.q[('w*dV_m', 0)]) + # GRADIENT OF TEST FUNCTIONS + self.q[('grad(w)', 0)] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nDOF_test_element[0], + self.nSpace_global), + 'd') + self.u[0].femSpace.getBasisGradientValues(self.elementQuadraturePoints, + self.q['inverse(J)'], + self.q[('grad(w)', 0)]) + self.q[('grad(w)*dV_f', 0)] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nDOF_test_element[0], + self.nSpace_global), + 'd') + cfemIntegrals.calculateWeightedShapeGradients(self.elementQuadratureWeights[('u', 0)], + self.q['abs(det(J))'], + self.q[('grad(w)', 0)], + self.q[('grad(w)*dV_f', 0)]) + ########################## + ### LUMPED MASS MATRIX ### + ########################## + # assume a linear mass term + dm = np.ones(self.q[('u', 0)].shape, 'd') + elementMassMatrix = np.zeros((self.mesh.nElements_global, + self.nDOF_test_element[0], + self.nDOF_trial_element[0]), 'd') + cfemIntegrals.updateMassJacobian_weak_lowmem(dm, + self.q[('w', 0)], + self.q[('w*dV_m', 0)], + elementMassMatrix) + self.MC_a = nzval.copy() + self.MC_global = SparseMat(self.nFreeDOF_global[0], + self.nFreeDOF_global[0], + nnz, + self.MC_a, + colind, + rowptr) + cfemIntegrals.zeroJacobian_CSR(self.nnz, self.MC_global) + cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.csrRowIndeces[(0, 0)], + self.csrColumnOffsets[(0, 0)], + elementMassMatrix, + self.MC_global) + self.ML = np.zeros((self.nFreeDOF_global[0],), 'd') + for i in range(self.nFreeDOF_global[0]): + self.ML[i] = self.MC_a[rowptr[i]:rowptr[i + 1]].sum() + np.testing.assert_almost_equal(self.ML.sum(), + self.mesh.volume, + err_msg="Trace of lumped mass matrix should be the domain volume", verbose=True) + for d in range(self.nSpace_global): # spatial dimensions + # C matrices + self.cterm[d] = np.zeros((self.mesh.nElements_global, + self.nDOF_test_element[0], + self.nDOF_trial_element[0]), 'd') + self.cterm_a[d] = nzval.copy() + #self.cterm_a[d] = np.zeros(nzval.size) + self.cterm_global[d] = SparseMat(self.nFreeDOF_global[0], + self.nFreeDOF_global[0], + nnz, + self.cterm_a[d], + colind, + rowptr) + cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global[d]) + di[:] = 0.0 + di[..., d] = 1.0 + cfemIntegrals.updateHamiltonianJacobian_weak_lowmem(di, + self.q[('grad(w)*dV_f', 0)], + self.q[('w', 0)], + self.cterm[d]) # int[(di*grad(wj))*wi*dV] + cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.csrRowIndeces[(0, 0)], + self.csrColumnOffsets[(0, 0)], + self.cterm[d], + self.cterm_global[d]) + # C Transpose matrices + self.cterm_transpose[d] = np.zeros((self.mesh.nElements_global, + self.nDOF_test_element[0], + self.nDOF_trial_element[0]), 'd') + self.cterm_a_transpose[d] = nzval.copy() + self.cterm_global_transpose[d] = SparseMat(self.nFreeDOF_global[0], + self.nFreeDOF_global[0], + nnz, + self.cterm_a_transpose[d], + colind, + rowptr) + cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global_transpose[d]) + di[:] = 0.0 + di[..., d] = -1.0 + cfemIntegrals.updateAdvectionJacobian_weak_lowmem(di, + self.q[('w', 0)], + self.q[('grad(w)*dV_f', 0)], + self.cterm_transpose[d]) # -int[(-di*grad(wi))*wj*dV] + cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.csrRowIndeces[(0, 0)], + self.csrColumnOffsets[(0, 0)], + self.cterm_transpose[d], + self.cterm_global_transpose[d]) + + rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() + else: + Cy = np.zeros(Cx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() + else: + Cz = np.zeros(Cx.shape, 'd') + rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() + else: + CTy = np.zeros(CTx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() + else: + CTz = np.zeros(CTx.shape, 'd') + + # This is dummy. I just care about the csr structure of the sparse matrix + self.dLow = np.zeros(Cx.shape, 'd') + self.fluxMatrix = np.zeros(Cx.shape, 'd') + self.dt_times_dC_minus_dL = np.zeros(Cx.shape, 'd') + nFree = len(rowptr)-1 + self.min_s_bc = np.zeros(nFree, 'd') + 1E10 + self.max_s_bc = np.zeros(nFree, 'd') - 1E10 + self.uDotLow = np.zeros(nFree, 'd') + self.uLow = np.zeros(nFree, 'd') + # + # cek end computationa of cterm_global + # + # cek showing mquezada an example of using cterm_global sparse matrix + # calculation y = c*x where x==1 + # direction=0 + #rowptr, colind, c = self.cterm_global[direction].getCSRrepresentation() + #y = np.zeros((self.nFreeDOF_global[0],),'d') + #x = np.ones((self.nFreeDOF_global[0],),'d') + # ij=0 + # for i in range(self.nFreeDOF_global[0]): + # for offset in range(rowptr[i],rowptr[i+1]): + # j = colind[offset] + # y[i] += c[ij]*x[j] + # ij+=1 + #Load the unknowns into the finite element dof + self.timeIntegration.calculateCoefs() + self.timeIntegration.calculateU(u) + self.setUnknowns(self.timeIntegration.u) + #cek can put in logic to skip of BC's don't depend on t or u + #Dirichlet boundary conditions + self.numericalFlux.setDirichletValues(self.ebqe) + #flux boundary conditions + #cek hack, just using advective flux for flux BC for now + for t,g in list(self.fluxBoundaryConditionsObjectsDict[0].advectiveFluxBoundaryConditionsDict.items()): + self.ebqe[('advectiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) + self.ebqe[('advectiveFlux_bc_flag',0)][t[0],t[1]] = 1 + # for t,g in self.fluxBoundaryConditionsObjectsDict[0].diffusiveFluxBoundaryConditionsDict.iteritems(): + # self.ebqe[('diffusiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) + # self.ebqe[('diffusiveFlux_bc_flag',0)][t[0],t[1]] = 1 + #self.shockCapturing.lag=True + if self.forceStrongConditions: + self.bc_mask = np.ones_like(self.u[0].dof) + for cj in range(len(self.dirichletConditionsForceDOF)): + for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): + self.u[cj].dof[dofN] = g(self.dirichletConditionsForceDOF[cj].DOFBoundaryPointDict[dofN],self.timeIntegration.t) + self.u_dof_old[dofN] = self.u[cj].dof[dofN] + self.bc_mask[dofN] = 0.0 + degree_polynomial = 1 + try: + degree_polynomial = self.u[0].femSpace.order + except: + pass + + argsDict = cArgumentsDict.ArgumentsDict() + if self.forceStrongConditions: + argsDict["bc_mask"] = self.bc_mask + argsDict["dt"] = self.timeIntegration.dt + argsDict["Theta"] = 1.0 + argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi + argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi + argsDict["mesh_dof"] = self.mesh.nodeArray + argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray + argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN + argsDict["mesh_l2g"] = self.mesh.elementNodesArray + argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] + argsDict["u_trial_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi + argsDict["u_test_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi + argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace + argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace + argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] + argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals + argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians + argsDict["nElements_global"] = self.mesh.nElements_global + argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] + argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, + argsDict["isSeepageFace"] = self.coefficients.isSeepageFace + argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] + argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] + argsDict["rho"] = self.coefficients.rho + argsDict["beta"] = self.coefficients.beta + argsDict["gravity"] = self.coefficients.gravity + argsDict["alpha"] = self.coefficients.vgm_alpha_types + argsDict["n"] = self.coefficients.vgm_n_types + argsDict["thetaR"] = self.coefficients.thetaR_types + argsDict["thetaSR"] = self.coefficients.thetaSR_types + argsDict["KWs"] = self.coefficients.Ksw_types + argsDict["useMetrics"] = 0.0 + argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf + argsDict["lag_shockCapturing"] = 0 + argsDict["shockCapturingDiffusion"] = 0.0 + argsDict["sc_uref"] = 0.0 + argsDict["sc_alpha"] = 0.0 + argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g + argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] + argsDict["elementDiameter"] = self.mesh.elementDiametersArray + argsDict["degree_polynomial"] = degree_polynomial + argsDict["u_dof"] = self.u[0].dof + argsDict["u_dof_old"] = self.u_dof_old + argsDict["velocity"] = self.q['velocity'] + argsDict["q_m"] = self.timeIntegration.m_tmp[0] + argsDict["q_u"] = self.q[('u',0)] + argsDict["q_dV"] = self.q[('dV_u',0)] + argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] + argsDict["cfl"] = self.q[('cfl',0)] + argsDict["q_numDiff_u"] = self.q[('cfl',0)] + argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] + argsDict["offset_u"] = self.offset[0] + argsDict["stride_u"] = self.stride[0] + argsDict["globalResidual"] = r + argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global + argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray + argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray + argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray + argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] + argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] + argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] + argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] + argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] + argsDict["ebqe_phi"] = self.ebqe[('u',0)] + argsDict["epsFact"] = 0.0 + argsDict["ebqe_u"] = self.ebqe[('u',0)] + argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] + argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE + # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION + argsDict["cE"] = self.coefficients.cE + argsDict["cK"] = self.coefficients.cK + # PARAMETERS FOR LOG BASED ENTROPY FUNCTION + argsDict["uL"] = self.coefficients.uL + argsDict["uR"] = self.coefficients.uR + # PARAMETERS FOR EDGE VISCOSITY + argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs + argsDict["NNZ"] = self.nnz + argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern + argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) + argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) + argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms + argsDict["globalJacobian"] = self.jacobian.getCSRrepresentation()[2] + # C matrices + argsDict["Cx"] = Cx + argsDict["Cy"] = Cy + argsDict["Cz"] = Cz + argsDict["CTx"] = CTx + argsDict["CTy"] = CTy + argsDict["CTz"] = CTz + argsDict["ML"] = self.ML + argsDict["delta_x_ij"] = self.delta_x_ij + # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE + argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE + # FLUX CORRECTED TRANSPORT + argsDict["dLow"] = self.dLow + argsDict["fluxMatrix"] = self.fluxMatrix + argsDict["uDotLow"] = self.uDotLow + argsDict["uLow"] = self.uLow + argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL + argsDict["min_s_bc"] = self.min_s_bc + argsDict["max_s_bc"] = self.max_s_bc + argsDict["quantDOFs"] = self.quantDOFs + argsDict["sLow"] = self.sLow + argsDict["sn"] = self.sn + if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG + self.calculateResidual = self.richards.calculateResidual + self.calculateJacobian = self.richards.calculateJacobian + else: + self.calculateResidual = self.richards.calculateResidual_entropy_viscosity + self.calculateJacobian = self.richards.calculateMassMatrix + if self.delta_x_ij is None: + self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') + self.calculateResidual(argsDict) + #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] + #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf + #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] + #self.timeIntegration.calculateElementCoefficients(self.q) + if self.forceStrongConditions:# + for cj in range(len(self.dirichletConditionsForceDOF)):# + for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): + r[self.offset[cj]+self.stride[cj]*dofN] = 0 + if self.stabilization: + self.stabilization.accumulateSubgridMassHistory(self.q) + logEvent("Global residual",level=9,data=r) + self.nonlinear_function_evaluations += 1 + if self.globalResidualDummy is None: + self.globalResidualDummy = np.zeros(r.shape,'d') + + def invert(self,u,r): + #u=s + #r=p + import pdb + import copy + """ + Calculate the element residuals and add in to the global residual + """ + self.sHigh[:] = u + rowptr, colind, nzval = self.jacobian.getCSRrepresentation() + nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix + r.fill(0.0) + rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() + else: + Cy = np.zeros(Cx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() + else: + Cz = np.zeros(Cx.shape, 'd') + rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() + else: + CTy = np.zeros(CTx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() + else: + CTz = np.zeros(CTx.shape, 'd') + + # This is dummy. I just care about the csr structure of the sparse matrix + nFree = len(rowptr)-1 + degree_polynomial = 1 + try: + degree_polynomial = self.u[0].femSpace.order + except: + pass + if self.delta_x_ij is None: + self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') + argsDict = cArgumentsDict.ArgumentsDict() + argsDict["dt"] = self.timeIntegration.dt + argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi + argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi + argsDict["mesh_dof"] = self.mesh.nodeArray + argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray + argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN + argsDict["mesh_l2g"] = self.mesh.elementNodesArray + argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] + argsDict["u_trial_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi + argsDict["u_test_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi + argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace + argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace + argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] + argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals + argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians + argsDict["nElements_global"] = self.mesh.nElements_global + argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] + argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, + argsDict["isSeepageFace"] = self.coefficients.isSeepageFace + argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] + argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] + argsDict["rho"] = self.coefficients.rho + argsDict["beta"] = self.coefficients.beta + argsDict["gravity"] = self.coefficients.gravity + argsDict["alpha"] = self.coefficients.vgm_alpha_types + argsDict["n"] = self.coefficients.vgm_n_types + argsDict["thetaR"] = self.coefficients.thetaR_types + argsDict["thetaSR"] = self.coefficients.thetaSR_types + argsDict["KWs"] = self.coefficients.Ksw_types + argsDict["useMetrics"] = 0.0 + argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf + argsDict["lag_shockCapturing"] = 0 + argsDict["shockCapturingDiffusion"] = 0.0 + argsDict["sc_uref"] = 0.0 + argsDict["sc_alpha"] = 0.0 + argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g + argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] + argsDict["elementDiameter"] = self.mesh.elementDiametersArray + argsDict["degree_polynomial"] = degree_polynomial + argsDict["u_dof"] = u#self.u[0].dof + argsDict["u_dof_old"] = self.u[0].dof + argsDict["velocity"] = self.q['velocity'] + argsDict["q_m"] = self.timeIntegration.m_tmp[0] + argsDict["q_u"] = self.q[('u',0)] + argsDict["q_dV"] = self.q[('dV_u',0)] + argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] + argsDict["cfl"] = self.q[('cfl',0)] + argsDict["q_numDiff_u"] = self.q[('cfl',0)] + argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] + argsDict["offset_u"] = self.offset[0] + argsDict["stride_u"] = self.stride[0] + argsDict["globalResidual"] = r + argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global + argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray + argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray + argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray + argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] + argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] + argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] + argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] + argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] + argsDict["ebqe_phi"] = self.ebqe[('u',0)] + argsDict["epsFact"] = 0.0 + argsDict["ebqe_u"] = self.ebqe[('u',0)] + argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] + argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE + # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION + argsDict["cE"] = self.coefficients.cE + argsDict["cK"] = self.coefficients.cK + # PARAMETERS FOR LOG BASED ENTROPY FUNCTION + argsDict["uL"] = self.coefficients.uL + argsDict["uR"] = self.coefficients.uR + # PARAMETERS FOR EDGE VISCOSITY + argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs + argsDict["NNZ"] = self.nnz + argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern + argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) + argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) + argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms + # C matrices + argsDict["Cx"] = Cx + argsDict["Cy"] = Cy + argsDict["Cz"] = Cz + argsDict["CTx"] = CTx + argsDict["CTy"] = CTy + argsDict["CTz"] = CTz + argsDict["ML"] = self.ML + argsDict["delta_x_ij"] = self.delta_x_ij + # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE + argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE + # FLUX CORRECTED TRANSPORT + argsDict["dLow"] = self.dLow + argsDict["fluxMatrix"] = self.fluxMatrix + argsDict["uDotLow"] = self.uDotLow + argsDict["uLow"] = self.uLow + argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL + argsDict["min_s_bc"] = self.min_s_bc + argsDict["max_s_bc"] = self.max_s_bc + argsDict["quantDOFs"] = self.quantDOFs + argsDict["sLow"] = self.sLow + argsDict["sn"] = self.sn + self.richards.invert(argsDict) + # self.timeIntegration.dt, + # self.u[0].femSpace.elementMaps.psi, + # self.u[0].femSpace.elementMaps.grad_psi, + # self.mesh.nodeArray, + # self.mesh.nodeVelocityArray, + # self.MOVING_DOMAIN, + # self.mesh.elementNodesArray, + # self.elementQuadratureWeights[('u',0)], + # self.u[0].femSpace.psi, + # self.u[0].femSpace.grad_psi, + # self.u[0].femSpace.psi, + # self.u[0].femSpace.grad_psi, + # #element boundary + # self.u[0].femSpace.elementMaps.psi_trace, + # self.u[0].femSpace.elementMaps.grad_psi_trace, + # self.elementBoundaryQuadratureWeights[('u',0)], + # self.u[0].femSpace.psi_trace, + # self.u[0].femSpace.grad_psi_trace, + # self.u[0].femSpace.psi_trace, + # self.u[0].femSpace.grad_psi_trace, + # self.u[0].femSpace.elementMaps.boundaryNormals, + # self.u[0].femSpace.elementMaps.boundaryJacobians, + # #physics + # self.mesh.nElements_global, + # self.ebqe['penalty'],#double* ebqe_penalty_ext, + # self.mesh.elementMaterialTypes,#int* elementMaterialTypes, + # self.coefficients.isSeepageFace, + # self.coefficients.sdInfo[(0,0)][0],#int* a_rowptr, + # self.coefficients.sdInfo[(0,0)][1],#int* a_colind, + # self.coefficients.rho,#double rho, + # self.coefficients.beta,#double beta, + # self.coefficients.gravity,#double* gravity, + # self.coefficients.vgm_alpha_types,#double* alpha, + # self.coefficients.vgm_n_types,#double* n, + # self.coefficients.thetaR_types,#double* thetaR, + # self.coefficients.thetaSR_types,#double* thetaSR, + # self.coefficients.Ksw_types,#double* KWs, + # False,#self.coefficients.useMetrics, + # self.timeIntegration.alpha_bdf, + # 0,#self.shockCapturing.lag, + # 0.0,#cek hack self.shockCapturing.shockCapturingFactor, + # 0.0,#self.coefficients.sc_uref, + # 0.0,#self.coefficients.sc_beta, + # self.u[0].femSpace.dofMap.l2g, + # self.l2g[0]['freeGlobal'], + # self.mesh.elementDiametersArray, + # degree_polynomial, + # self.sHigh, + # self.u_dof_old, + # self.q['velocity'],#self.coefficients.q_v, + # self.timeIntegration.m_tmp[0], + # self.q[('u',0)], + # self.timeIntegration.beta_bdf[0], + # self.q[('cfl',0)], + # self.edge_based_cfl, + # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff[0], + # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff_last[0], + # self.offset[0],self.stride[0], + # r, + # self.mesh.nExteriorElementBoundaries_global, + # self.mesh.exteriorElementBoundariesArray, + # self.mesh.elementBoundaryElementsArray, + # self.mesh.elementBoundaryLocalElementBoundariesArray, + # self.ebqe['velocity'],#self.coefficients.ebqe_v, + # self.numericalFlux.isDOFBoundary[0], + # self.numericalFlux.ebqe[('u',0)], + # self.ebqe[('advectiveFlux_bc_flag',0)], + # self.ebqe[('advectiveFlux_bc',0)], + # self.ebqe[('u',0)],#cek hack self.coefficients.ebqe_phi, + # 0.0,#cek hack self.coefficients.epsFact, + # self.ebqe[('u',0)], + # self.ebqe[('advectiveFlux',0)], + # # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION + # self.coefficients.cE, + # self.coefficients.cK, + # # PARAMETERS FOR LOG BASED ENTROPY FUNCTION + # self.coefficients.uL, + # self.coefficients.uR, + # # PARAMETERS FOR EDGE VISCOSITY + # len(rowptr) - 1, # num of DOFs + # len(Cx), # num of non-zero entries in the sparsity pattern + # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) + # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) + # self.csrRowIndeces[(0, 0)], # row indices (convenient for element loops) + # self.csrColumnOffsets[(0, 0)], # column indices (convenient for element loops) + # self.csrColumnOffsets_eb[(0, 0)], # indices for boundary terms + # # C matrices + # Cx, + # Cy, + # Cz, + # CTx, + # CTy, + # CTz, + # self.ML, + # self.delta_x_ij, + # # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + # self.coefficients.LUMPED_MASS_MATRIX, + # self.coefficients.STABILIZATION_TYPE, + # self.coefficients.ENTROPY_TYPE, + # # FLUX CORRECTED TRANSPORT + # self.dLow, + # self.fluxMatrix, + # self.uDotLow, + # self.uLow, + # self.dt_times_dC_minus_dL, + # self.min_s_bc, + # self.max_s_bc, + # self.quantDOFs) + #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] + #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf + #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] + #self.timeIntegration.calculateElementCoefficients(self.q) + #if self.forceStrongConditions:# + # for cj in range(len(self.dirichletConditionsForceDOF)):# + # for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): + # r[self.offset[cj]+self.stride[cj]*dofN] = 0 + #if self.stabilization: + # self.stabilization.accumulateSubgridMassHistory(self.q) + #logEvent("Global residual",level=9,data=r) + #self.nonlinear_function_evaluations += 1 + #if self.globalResidualDummy is None: + # self.globalResidualDummy = numpy.zeros(r.shape,'d') + def getJacobian(self,jacobian): + if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG + cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, + jacobian) + degree_polynomial = 1 + try: + degree_polynomial = self.u[0].femSpace.order + except: + pass + if self.delta_x_ij is None: + self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') + argsDict = cArgumentsDict.ArgumentsDict() + argsDict["dt"] = self.timeIntegration.dt + argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi + argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi + argsDict["mesh_dof"] = self.mesh.nodeArray + argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray + argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN + argsDict["mesh_l2g"] = self.mesh.elementNodesArray + argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] + argsDict["u_trial_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi + argsDict["u_test_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi + argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace + argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace + argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] + argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals + argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians + argsDict["nElements_global"] = self.mesh.nElements_global + argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] + argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, + argsDict["isSeepageFace"] = self.coefficients.isSeepageFace + argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] + argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] + argsDict["rho"] = self.coefficients.rho + argsDict["beta"] = self.coefficients.beta + argsDict["gravity"] = self.coefficients.gravity + argsDict["alpha"] = self.coefficients.vgm_alpha_types + argsDict["n"] = self.coefficients.vgm_n_types + argsDict["thetaR"] = self.coefficients.thetaR_types + argsDict["thetaSR"] = self.coefficients.thetaSR_types + argsDict["KWs"] = self.coefficients.Ksw_types + argsDict["useMetrics"] = 0.0 + argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf + argsDict["lag_shockCapturing"] = 0 + argsDict["shockCapturingDiffusion"] = 0.0 + argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g + argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] + argsDict["elementDiameter"] = self.mesh.elementDiametersArray + argsDict["degree_polynomial"] = degree_polynomial + argsDict["u_dof"] = self.u[0].dof + argsDict["velocity"] = self.q['velocity'] + argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] + argsDict["cfl"] = self.q[('cfl',0)] + argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] + argsDict["csrRowIndeces_u_u"] = self.csrRowIndeces[(0,0)] + argsDict["csrColumnOffsets_u_u"] = self.csrColumnOffsets[(0,0)] + argsDict["globalJacobian"] = jacobian.getCSRrepresentation()[2] + argsDict["delta_x_ij"] = self.delta_x_ij + argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global + argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray + argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray + argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray + argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] + argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] + argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] + argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] + argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] + argsDict["csrColumnOffsets_eb_u_u"] = self.csrColumnOffsets_eb[(0,0)] + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + self.calculateJacobian(argsDict) + if self.forceStrongConditions: + for dofN in list(self.dirichletConditionsForceDOF[0].DOFBoundaryConditionsDict.keys()): + global_dofN = self.offset[0]+self.stride[0]*dofN + self.nzval[np.where(self.colind == global_dofN)] = 0.0 #column + self.nzval[self.rowptr[global_dofN]:self.rowptr[global_dofN+1]] = 0.0 #row + zeroRow=True + for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]):#row + if (self.colind[i] == global_dofN): + self.nzval[i] = 1.0 + zeroRow = False + if zeroRow: + raise RuntimeError("Jacobian has a zero row because sparse matrix has no diagonal entry at row "+repr(global_dofN)+". You probably need add diagonal mass or reaction term") + #scaling = 1.0#probably want to add some scaling to match non-dirichlet diagonals in linear system + #for cj in range(self.nc): + # for dofN in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.keys()): + # global_dofN = self.offset[cj]+self.stride[cj]*dofN + # for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]): + # if (self.colind[i] == global_dofN): + # self.nzval[i] = scaling + # else: + # self.nzval[i] = 0.0 + logEvent("Jacobian ",level=10,data=jacobian) + #mwf decide if this is reasonable for solver statistics + self.nonlinear_function_jacobian_evaluations += 1 + return jacobian + def calculateElementQuadrature(self): + """ + Calculate the physical location and weights of the quadrature rules + and the shape information at the quadrature points. + + This function should be called only when the mesh changes. + """ + #self.u[0].femSpace.elementMaps.getValues(self.elementQuadraturePoints, + # self.q['x']) + self.u[0].femSpace.elementMaps.getBasisValuesRef(self.elementQuadraturePoints) + self.u[0].femSpace.elementMaps.getBasisGradientValuesRef(self.elementQuadraturePoints) + self.u[0].femSpace.getBasisValuesRef(self.elementQuadraturePoints) + self.u[0].femSpace.getBasisGradientValuesRef(self.elementQuadraturePoints) + self.coefficients.initializeElementQuadrature(self.timeIntegration.t,self.q) + if self.stabilization != None: + self.stabilization.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) + self.stabilization.initializeTimeIntegration(self.timeIntegration) + if self.shockCapturing != None: + self.shockCapturing.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) + def calculateElementBoundaryQuadrature(self): + pass + def calculateExteriorElementBoundaryQuadrature(self): + """ + Calculate the physical location and weights of the quadrature rules + and the shape information at the quadrature points on global element boundaries. + + This function should be called only when the mesh changes. + """ + # + #get physical locations of element boundary quadrature points + # + #assume all components live on the same mesh + self.u[0].femSpace.elementMaps.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.elementMaps.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.elementMaps.getValuesGlobalExteriorTrace(self.elementBoundaryQuadraturePoints, + self.ebqe['x']) + self.fluxBoundaryConditionsObjectsDict = dict([(cj,FluxBoundaryConditions(self.mesh, + self.nElementBoundaryQuadraturePoints_elementBoundary, + self.ebqe[('x')], + getAdvectiveFluxBoundaryConditions=self.advectiveFluxBoundaryConditionsSetterDict[cj], + getDiffusiveFluxBoundaryConditions=self.diffusiveFluxBoundaryConditionsSetterDictDict[cj])) + for cj in list(self.advectiveFluxBoundaryConditionsSetterDict.keys())]) + self.coefficients.initializeGlobalExteriorElementBoundaryQuadrature(self.timeIntegration.t,self.ebqe) + def estimate_mt(self): + pass + def calculateSolutionAtQuadrature(self): + pass + def calculateAuxiliaryQuantitiesAfterStep(self): + pass \ No newline at end of file diff --git a/richards_fct/richards/edit/Richards_corrupted.h b/richards_fct/richards/edit/Richards_corrupted.h new file mode 100644 index 0000000000..36a10ac428 --- /dev/null +++ b/richards_fct/richards/edit/Richards_corrupted.h @@ -0,0 +1,3205 @@ +#ifndef Richards_H +#define Richards_H +#include +#include +#include +#include "CompKernel.h" +#include "ModelFactory.h" +#include "../mprans/ArgumentsDict.h" +#include "xtensor-python/pyarray.hpp" +#define nnz nSpace + +namespace py = pybind11; +#define POWER_SMOOTHNESS_INDICATOR 2 +#define IS_BETAij_ONE 0 +#define GLOBAL_FCT 0 +namespace proteus +{ + // Power entropy // + inline double ENTROPY(const double& phi, const double& phiL, const double& phiR){ + return 1./2.*std::pow(fabs(phi),2.); + } + inline double DENTROPY(const double& phi, const double& phiL, const double& phiR){ + return fabs(phi)*(phi>=0 ? 1 : -1); + } + // Log entropy // for level set from 0 to 1 + inline double ENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ + return std::log(fabs((phi-phiL)*(phiR-phi))+1E-14); + } + inline double DENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ + return (phiL+phiR-2*phi)*((phi-phiL)*(phiR-phi)>=0 ? 1 : -1)/(fabs((phi-phiL)*(phiR-phi))+1E-14); + } +} + +namespace proteus + +{ + class Richards_base + { + //The base class defining the interface + public: + virtual ~Richards_base(){ + double anb_seepage_flux =1e-16; + } + virtual void calculateResidual(arguments_dict& args)=0; + virtual void calculateJacobian(arguments_dict& args)=0; + virtual void invert(arguments_dict& args)=0; + virtual void FCTStep(arguments_dict& args)=0; + virtual void kth_FCT_step(arguments_dict& args)=0; + virtual void calculateResidual_entropy_viscosity(arguments_dict& args)=0; + virtual void calculateMassMatrix(arguments_dict& args)=0; + }; + + template + class Richards : public Richards_base + { + public: + const int nDOF_test_X_trial_element; + CompKernelType ck; + Richards(): + nDOF_test_X_trial_element(nDOF_test_element*nDOF_trial_element), + ck() + {} + inline + void evaluateCoefficients(const int rowptr[nSpace], + const int colind[nnz], + const double rho, + const double beta, + const double gravity[nSpace], + const double alpha, + const double n_vg, + const double thetaR, + const double thetaSR, + const double KWs[nnz], + const double& u, + double& m, + double& dm, + double f[nSpace], + double df[nSpace], + double a[nnz], + double da[nnz], + double as[nnz], + double& kr, + double& dkr) + { + const int nSpace2 = nSpace * nSpace; + double psiC; + double pcBar; + double pcBar_n; + double pcBar_nM1; + double pcBar_nM2; + double onePlus_pcBar_n; + double sBar; + double sqrt_sBar; + double DsBar_DpsiC; + double thetaW; + double DthetaW_DpsiC; + double vBar; + double vBar2; + double DvBar_DpsiC; + double KWr; + double DKWr_DpsiC; + double rho2 = rho * rho; + double thetaS; + double rhom; + double drhom; + double m_vg; + double pcBarStar; + double sqrt_sBarStar; + + psiC = -u; + m_vg = 1.0 - 1.0 / n_vg; + thetaS = thetaR + thetaSR; + //std::cout<< "Thetas"< 0.0) + { + pcBar = alpha * psiC; + pcBarStar = pcBar; + if (pcBar < 1.0e-8) + pcBarStar = 1.0e-8; + pcBar_nM2 = pow(pcBarStar, n_vg - 2); + pcBar_nM1 = pcBar_nM2 * pcBar; + pcBar_n = pcBar_nM1 * pcBar; + onePlus_pcBar_n = 1.0 + pcBar_n; + + sBar = pow(onePlus_pcBar_n, -m_vg); + /* using -mn = 1-n */ + DsBar_DpsiC = alpha * (1.0 - n_vg) * (sBar/onePlus_pcBar_n)*pcBar_nM1; + + vBar = 1.0-pcBar_nM1*sBar; + vBar2 = vBar*vBar; + DvBar_DpsiC = -alpha*(n_vg-1.0)*pcBar_nM2*sBar - pcBar_nM1*DsBar_DpsiC; + + thetaW = thetaSR*sBar + thetaR; + DthetaW_DpsiC = thetaSR * DsBar_DpsiC; + + sqrt_sBar = sqrt(sBar); + sqrt_sBarStar = sqrt_sBar; + if (sqrt_sBar < 1.0e-8) + sqrt_sBarStar = 1.0e-8; + KWr= sqrt_sBar*vBar2; + DKWr_DpsiC= ((0.5/sqrt_sBarStar)*DsBar_DpsiC*vBar2 + + + 2.0*sqrt_sBar*vBar*DvBar_DpsiC); + } + else + { + thetaW = thetaS; + DthetaW_DpsiC = 0.0; + KWr = 1.0; + DKWr_DpsiC = 0.0; + } + //slight compressibility + rhom = rho*exp(beta*u); + drhom = beta*rhom; + m = rhom*thetaW; + dm = -rhom*DthetaW_DpsiC+drhom*thetaW; + for (int I=0;I thetaS || thetaW <= thetaR) + { + //cek debug + std::cout<<"rho "< 0.0) + { + isDOFBoundary = 1; + bc_u = bc_u_seepage; + } + else + { + isDOFBoundary = 0; + flux = 0.0; + } + } + /* //set DOF flag and flux correctly if seepage face */ + /* if (isSeepageFace) */ + /* { */ + /* if (flux < 0.0 || u < bc_u_seepage) */ + /* { */ + /* isDOFBoundary = 0; */ + /* flux = 0.0; */ + /* } */ + /* else */ + /* { */ + /* isDOFBoundary = 1; */ + /* bc_u = bc_u_seepage; */ + /* } */ + /* } */ + /* //Dirichlet penalty */ + /* if (isDOFBoundary) */ + /* flux += penalty*(u-bc_u); */ + } + else + flux = bc_flux; + } + + void exteriorNumericalFluxJacobian(const int rowptr[nSpace], + const int colind[nnz], + const int isDOFBoundary, + const double n[nSpace], + const double K[nnz], + const double dK[nnz], + const double grad_psi[nSpace], + const double grad_v[nSpace], + const double dK_rho_g[nSpace], + const double v, + const double penalty, + double& fluxJacobian) + { + if (isDOFBoundary) + { + fluxJacobian = 0.0; + for(int I=0;I& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + double sc_uref = args.scalar("sc_uref"); + double sc_alpha = args.scalar("sc_alpha"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& u_dof_old = args.array("u_dof_old"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m = args.array("q_m"); + xt::pyarray& q_u = args.array("q_u"); + xt::pyarray& q_dV = args.array("q_dV"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + int offset_u = args.scalar("offset_u"); + int stride_u = args.scalar("stride_u"); + xt::pyarray& globalResidual = args.array("globalResidual"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& ebqe_phi = args.array("ebqe_phi"); + double epsFact = args.scalar("epsFact"); + xt::pyarray& ebqe_u = args.array("ebqe_u"); + xt::pyarray& ebqe_flux = args.array("ebqe_flux"); + // PARAMETERS FOR EDGE BASED STABILIZATION + double cE = args.scalar("cE"); + double cK = args.scalar("cK"); + // PARAMETERS FOR LOG BASED ENTROPY FUNCTION + double uL = args.scalar("uL"); + double uR = args.scalar("uR"); + // PARAMETERS FOR EDGE VISCOSITY + int numDOFs = args.scalar("numDOFs"); + int NNZ = args.scalar("NNZ"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); + xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); + xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); + xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); + // C matrices + xt::pyarray& Cx = args.array("Cx"); + xt::pyarray& Cy = args.array("Cy"); + xt::pyarray& Cz = args.array("Cz"); + xt::pyarray& CTx = args.array("CTx"); + xt::pyarray& CTy = args.array("CTy"); + xt::pyarray& CTz = args.array("CTz"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); + int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); + // FOR FCT + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& fluxMatrix = args.array("fluxMatrix"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); + xt::pyarray& min_s_bc = args.array("min_s_bc"); + xt::pyarray& max_s_bc = args.array("max_s_bc"); + // AUX QUANTITIES OF INTEREST + xt::pyarray& quantDOFs = args.array("quantDOFs"); + xt::pyarray& sLow = args.array("sLow"); + xt::pyarray& sn = args.array("sn"); + + assert(a_rowptr.data()[nSpace] == nnz); + assert(a_rowptr.data()[nSpace] == nSpace); + //cek should this be read in? + double Ct_sge = 4.0; + //For flux Calculation + //double anb_seepage_flux=0.0; + //anb_seepage_flux = args["anb_seepage_flux"]; + //double anb_seepage_flux = args.scalar("anb_seepage_flux"); + //anb_seepage_flux=0.0; + + xt::pyarray& anb_seepage_flux_n = args.array("anb_seepage_flux_n"); + + + //double anb_seepage_flux=0.0; + double & anb_seepage_flux (args.scalar("anb_seepage_flux")) ; + //double anb_seepage_flux = args.scalar("anb_seepage_flux_n"); + + //double anb_seepage_flux=0.0; + anb_seepage_flux=0.0; + + //loop over elements to compute volume integrals and load them into element and global residual + // + //eN is the element index + //eN_k is the quadrature point index for a scalar + //eN_k_nSpace is the quadrature point index for a vector + //eN_i is the element test function index + //eN_j is the element trial function index + //eN_k_j is the quadrature point index for a trial function + //eN_k_i is the quadrature point index for a trial function + for(int eN=0;eN0) + { + std::cout<<"The seepage flux is "<& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); + xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); + xt::pyarray& globalJacobian = args.array("globalJacobian"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + assert(a_rowptr.data()[nSpace] == nnz); + assert(a_rowptr.data()[nSpace] == nSpace); + double Ct_sge = 4.0; + + + // + //loop over elements to compute volume integrals and load them into the element Jacobians and global Jacobian + // + for(int eN=0;eN& bc_mask = args.array("bc_mask"); + int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern + int numDOFs = args.scalar("numDOFs"); //number of DOFs + double dt = args.scalar("dt"); + xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) + xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn + xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn + xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& limited_solution = args.array("limited_solution"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets + xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices + xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 + xt::pyarray& max_s_bc = args.array("max_s_bc"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int MONOLITHIC = args.scalar("MONOLITHIC"); + register double Rpos[numDOFs], Rneg[numDOFs]; + register double FluxCorrectionMatrix[NNZ]; + register double solL[numDOFs]; + register double sdot[numDOFs]; + ////////////////// + // LOOP in DOFs // + ////////////////// + int ij=0; + for (int i=0; i 0) ? 1. : 0.); + Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); + + //update ij + ij+=1; + //std::cout<<"sdoti error"<0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])) + * FluxCorrectionMatrix[ij]; + alpha_dot = fmin(1.0, beta_ij*fabs(alpha_fA)/MassMatrix.data()[ij]/fmax(1.0e-8,fabs(sdoti-sdotj))); + if (MONOLITHIC == 0) + { + ith_Limiter_times_FluxCorrectionMatrix += alpha_fA; + } + else + { + ith_Limiter_times_FluxCorrectionMatrix += alpha_fA + (LUMPED_MASS_MATRIX == 1 ? 0. : 1.)*dt*alpha_dot*MassMatrix.data()[ij]*(sdoti-sdotj); + } + //update ij + ij+=1; + } + limited_solution.data()[i] = solL[i] + 1./lumped_mass_matrix.data()[i]*ith_Limiter_times_FluxCorrectionMatrix*bc_mask[i]; + } + } + + void kth_FCT_step(arguments_dict& args) + { + int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern + int numDOFs = args.scalar("numDOFs"); //number of DOFs + int num_fct_iter = args.scalar("num_fct_iter"); + double dt = args.scalar("dt"); + xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) + xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn + xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn + xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& solLim = args.array("limited_solution"); + xt::pyarray& MC = args.array("MC"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& FluxMatrix = args.array("FluxMatrix"); + xt::pyarray& limitedFlux = args.array("limited_Flux"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets + xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices + xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 + xt::pyarray& max_s_bc = args.array("max_s_bc"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int MONOLITHIC = args.scalar("MONOLITHIC"); + register double Rpos[numDOFs], Rneg[numDOFs]; + int ij=0; + + ////////////////////////////////////////////////////// + // ********** COMPUTE LOW ORDER SOLUTION ********** // + ////////////////////////////////////////////////////// + if (num_fct_iter == 0) + { // No FCT for global bounds + for (int i=0; i 0) ? 1. : 0.); + // update ij + ij+=1; + } + // compute Q vectors + double mi = ML.data()[i]; + double solLimi = solLim.data()[i]; + double Qposi = mi*(maxi-solLimi); + // compute R vectors + Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + } + ij=0; + for (int i=0; i0 ? Rposi : Rpos[j]); + // compute limited flux + ith_Limiter_times_FluxCorrectionMatrix += Lij*Fluxij; + + // update limited flux + limitedFlux.data()[ij] = Lij*Fluxij; + + //update FluxMatrix + FluxMatrix.data()[ij] = Fluxij; + + //update ij + ij+=1; + } + //update limited solution + double mi = ML.data()[i]; + solLim.data()[i] += 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; + } + } + } + + // ***************************************** // + // ********** HIGH ORDER SOLUTION ********** // + // ***************************************** // + ij=0; + for (int i=0; i 0 ? 1. : 0.); + Pnegi += fij * (fij < 0 ? 1. : 0.); + //update ij + ij+=1; + } + // compute Q vectors // + double mi = ML.data()[i]; + double Qposi = mi*(maxi-solLim.data()[i]); + double Qnegi = mi*(mini-solLim.data()[i]); + // compute R vectors // + Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); + } + + // COMPUTE LIMITERS // + ij=0; + for (int i=0; i 0 ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j]); + // compute ith_limited_flux_correction + ith_limited_flux_correction += Lij*fij; + ij+=1; + } + double mi = ML.data()[i]; + solLim[i] += 1./mi*ith_limited_flux_correction; + } + } + + void calculateResidual_entropy_viscosity(arguments_dict& args) + { + xt::pyarray& globalJacobian = args.array("globalJacobian"); + double Theta = args.scalar("Theta"); + xt::pyarray& bc_mask = args.array("bc_mask"); + double dt = args.scalar("dt"); + xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + double sc_uref = args.scalar("sc_uref"); + double sc_alpha = args.scalar("sc_alpha"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& r_l2g = args.array("r_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + int degree_polynomial = args.scalar("degree_polynomial"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& u_dof_old = args.array("u_dof_old"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m = args.array("q_m"); + xt::pyarray& q_u = args.array("q_u"); + xt::pyarray& q_dV = args.array("q_dV"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + int offset_u = args.scalar("offset_u"); + int stride_u = args.scalar("stride_u"); + xt::pyarray& globalResidual = args.array("globalResidual"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& ebqe_phi = args.array("ebqe_phi"); + double epsFact = args.scalar("epsFact"); + xt::pyarray& ebqe_u = args.array("ebqe_u"); + xt::pyarray& ebqe_flux = args.array("ebqe_flux"); + // PARAMETERS FOR EDGE BASED STABILIZATION + double cE = args.scalar("cE"); + double cK = args.scalar("cK"); + // PARAMETERS FOR LOG BASED ENTROPY FUNCTION + double uL = args.scalar("uL"); + double uR = args.scalar("uR"); + // PARAMETERS FOR EDGE VISCOSITY + int numDOFs = args.scalar("numDOFs"); + int NNZ = args.scalar("NNZ"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); + xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); + xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); + xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); + // C matrices + xt::pyarray& Cx = args.array("Cx"); + xt::pyarray& Cy = args.array("Cy"); + xt::pyarray& Cz = args.array("Cz"); + xt::pyarray& CTx = args.array("CTx"); + xt::pyarray& CTy = args.array("CTy"); + xt::pyarray& CTz = args.array("CTz"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); + int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); + // FOR FCT + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& fluxMatrix = args.array("fluxMatrix"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); + xt::pyarray& min_s_bc = args.array("min_s_bc"); + xt::pyarray& max_s_bc = args.array("max_s_bc"); + // AUX QUANTITIES OF INTEREST + xt::pyarray& quantDOFs = args.array("quantDOFs"); + xt::pyarray& sLow = args.array("sLow"); + xt::pyarray& sn = args.array("sn"); + + xt::pyarray& anb_seepage_flux_n = args.array("anb_seepage_flux_n"); + + + //double anb_seepage_flux=0.0; + double & anb_seepage_flux (args.scalar("anb_seepage_flux")) ; + //double anb_seepage_flux = args.scalar("anb_seepage_flux_n"); + + //double anb_seepage_flux=0.0; + anb_seepage_flux=0.0; + + + register double Rpos[numDOFs], Rneg[numDOFs]; + //register double FluxCorrectionMatrix[NNZ]; + // NOTE: This function follows a different (but equivalent) implementation of the smoothness based indicator than NCLS.h + // Allocate space for the transport matrices + // This is used for first order KUZMIN'S METHOD + register double TransportMatrix[NNZ],TransportMatrixConsistent[NNZ]; + register double TransportMatrixn[NNZ],TransportMatrixConsistentn[NNZ]; + std::valarray u_free_dof(numDOFs); + std::valarray u_free_dof_old(numDOFs); + std::valarray ML2(numDOFs); + + + for(int eN=0;eN0) + { + std::cout<<"The seepage flux is "<("anb_seepage_flux_n"); + //anb_seepage_flux_n=0.0; + + //anb_seepage_flux_n= anb_seepage_flux; + + + + //if (isSeepageFace) + //{ + // anb_seepage_flux+= dS* flux_ext; + // std::cout<<"The seepage flux is "<0){ + // std::cout<<"The seepage flux is "<= 0 && isFluxBoundary_u[ebNE_kb] != 1 ) //outflow. This is handled via the transport matrices. Then flux_ext=0 and dflux_ext!=0 + // { + // dflux_ext = flow; + // flux_ext = 0; + // // save external u + // ebqe_u[ebNE_kb] = u_ext; + // } + //else // inflow. This is handled via the boundary integral. Then flux_ext!=0 and dflux_ext=0 + //{ + //dflux_ext = 0; + // save external u + //ebqe_u[ebNE_kb] = isDOFBoundary_u[ebNE_kb]*ebqe_bc_u_ext[ebNE_kb]+(1-isDOFBoundary_u[ebNE_kb])*u_ext; + //if (isDOFBoundary_u[ebNE_kb] == 1) + // flux_ext = ebqe_bc_u_ext[ebNE_kb]*flow; + //else if (isFluxBoundary_u[ebNE_kb] == 1) + //flux_ext = ebqe_bc_flux_u_ext[ebNE_kb]; + // flux_ext = ebqe_bc_u_ext[ebNE_kb]; + //else + // { + // std::cout<<"warning: VOF open boundary with no external trace, setting to zero for inflow"<= 0.) + { + alpha_numerator_pos += alpha_num; + alpha_denominator_pos += alpha_num; + } + else + { + alpha_numerator_neg += alpha_num; + alpha_denominator_neg += fabs(alpha_num); + } + //update ij + ij+=1; + } + // scale g vector by lumped mass matrix + if (fabs(ML.data()[i] - ML2[i]) > 1.0e-16) + std::cout<<"ML "< 0.0) + // assert( (xi[I] - xj[I]) == delta_x_ij[offset*3+I]); + //gi_times_x += gi[I]*(xi[I]-xj[I]); + gi_times_x += gi[I]*delta_x_ij.data()[offset*3+I]; + } + // compute the positive and negative part of gi*(xi-xj) + SumPos += gi_times_x > 0 ? gi_times_x : 0; + SumNeg += gi_times_x < 0 ? gi_times_x : 0; + } + double sigmaPosi = fmin(1.,(fabs(SumNeg)+1E-15)/(SumPos+1E-15)); + double sigmaNegi = fmin(1.,(SumPos+1E-15)/(fabs(SumNeg)+1E-15)); + double alpha_numi = fabs(sigmaPosi*alpha_numerator_pos + sigmaNegi*alpha_numerator_neg); + double alpha_deni = sigmaPosi*alpha_denominator_pos + sigmaNegi*alpha_denominator_neg; + if (IS_BETAij_ONE == 1) + { + alpha_numi = fabs(alpha_numerator_pos + alpha_numerator_neg); + alpha_deni = alpha_denominator_pos + alpha_denominator_neg; + } + double alphai = alpha_numi/(alpha_deni+1E-15); + quantDOFs.data()[i] = alphai; + + if (POWER_SMOOTHNESS_INDICATOR==0) + psi[i] = 1.0; + else + psi[i] = std::pow(alphai,POWER_SMOOTHNESS_INDICATOR); //NOTE: they use alpha^2 in the paper + } + ///////////////////////////////////////////// + // ** LOOP IN DOFs FOR EDGE BASED TERMS ** // + ///////////////////////////////////////////// + ij=0; + for (int i=0; i Dissipation matrices as well. + double soli = u_free_dof[i]; // solution at time tn for the ith DOF + double solni = u_free_dof_old[i]; // solution at time tn for the ith DOF + for (int I=0;I mMax) + { + std::cout<<"mass out of bounds "< 0) ? 1. : 0.); + // Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); + // ij+=1; + // } + // double mi = ML[i]; + // double solni = u_dof_old[i]; + // double Qposi = mi*(maxi-solni); + // double Qnegi = mi*(mini-solni); + + //std::cout << Qposi << std::endl; + // Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + // Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); + + //if (Rpos[i] < 0) + //{ + // std::cout << mi << "\t" << maxi << "\t" << solni << std::endl; + // std::cout << Qposi << "\t" << Pposi << std::endl; + // std::cout << Rpos[i] << std::endl; + //abort(); + //} + //} + + //ij=0; + //for (int i=0; i 1.0 || Rposi < 0.0) + //std::cout << "Rposi: " << Rposi << std::endl; + //if (Rnegi > 1.0 || Rnegi < 0.0) + //std::cout << "Rnegi: " << Rnegi << std::endl; + + // LOOP OVER THE SPARSITY PATTERN (j-LOOP)// + // for (int offset=csrRowIndeces_DofLoops.data()[i]; + // offset0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])); + // //Lij=0.0; + // ith_Limiter_times_FluxCorrectionMatrix += Lij*FluxCorrectionMatrix[ij]; + // //update ij + // ij+=1; + // } + // double mi = ML[i]; + // double solni = u_dof_old[i]; + // globalResidual[i] = solni + 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; + //} + } + + + void invert(arguments_dict& args) + { + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + xt::pyarray& globalResidual = args.array("globalResidual"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + int numDOFs = args.scalar("numDOFs"); + for (int i=0; i mMax) + { + std::cout<<"mass out of bounds "<("dt"); + xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + //element boundary + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + //physics + int nElements_global = args.scalar("nElements_global"); + //new + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + //end new + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& r_l2g = args.array("r_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + int degree_polynomial = args.scalar("degree_polynomial"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); + xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); + xt::pyarray& globalJacobian = args.array("globalJacobian"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + //std::cout<<"ndjaco address "<(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + else if (nSpaceIn == 2) + return proteus::chooseAndAllocateDiscretization2D(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + else + { + assert(nSpaceIn == 3); + return proteus::chooseAndAllocateDiscretization(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + } + } +};//proteus +#endif \ No newline at end of file diff --git a/richards_fct/richards/edit/Richards_corrupted.py b/richards_fct/richards/edit/Richards_corrupted.py new file mode 100644 index 0000000000..7199b31595 --- /dev/null +++ b/richards_fct/richards/edit/Richards_corrupted.py @@ -0,0 +1,1848 @@ +from __future__ import division +from builtins import range +from past.utils import old_div +import proteus +from .cRichards import * +import numpy as np +from proteus.Transport import OneLevelTransport +from proteus.Transport import TC_base, NonlinearEquation, logEvent, memory +from proteus.Transport import FluxBoundaryConditions, Comm, cfemIntegrals +from proteus.Transport import DOFBoundaryConditions, Quadrature +from proteus.mprans import cArgumentsDict +from proteus.LinearAlgebraTools import SparseMat +from proteus import TimeIntegration +from proteus.NonlinearSolvers import ExplicitLumpedMassMatrixForRichards + +class ThetaScheme(TimeIntegration.BackwardEuler): + def __init__(self,transport,integrateInterpolationPoints=False): + self.transport=transport + TimeIntegration.BackwardEuler.__init__(self,transport, integrateInterpolationPoints) + def updateTimeHistory(self,resetFromDOF=False): + TimeIntegration.BackwardEuler.updateTimeHistory(self,resetFromDOF) + self.transport.u_dof_old[:] = self.u +class RKEV(TimeIntegration.SSP): + from proteus import TimeIntegration + """ + Wrapper for SSPRK time integration using EV + + ... more to come ... + """ + + def __init__(self, transport, timeOrder=1, runCFL=0.1, integrateInterpolationPoints=False): + TimeIntegration.SSP.__init__(self, transport, integrateInterpolationPoints=integrateInterpolationPoints) + self.runCFL = runCFL + self.dtLast = None + self.isAdaptive = True + # About the cfl + assert transport.coefficients.STABILIZATION_TYPE > 0, "SSP method just works for edge based EV methods; i.e., STABILIZATION_TYPE>0" + assert hasattr(transport, 'edge_based_cfl'), "No edge based cfl defined" + self.cfl = transport.edge_based_cfl + # Stuff particular for SSP + self.timeOrder = timeOrder # order of approximation + self.nStages = timeOrder # number of stages total + self.lstage = 0 # last stage completed + # storage vectors + self.u_dof_last = {} + # per component stage values, list with array at each stage + self.u_dof_stage = {} + for ci in range(self.nc): + if ('m', ci) in transport.q: + self.u_dof_last[ci] = transport.u[ci].dof.copy() + self.u_dof_stage[ci] = [] + for k in range(self.nStages + 1): + self.u_dof_stage[ci].append(transport.u[ci].dof.copy()) + #print() + + + # def set_dt(self, DTSET): + # self.dt = DTSET # don't update t + def choose_dt(self): + comm = Comm.get() + maxCFL = 1.0e-6 + maxCFL = max(maxCFL, comm.globalMax(self.cfl.max())) + self.dt = old_div(self.runCFL, maxCFL) + if self.dtLast is None: + self.dtLast = self.dt + self.t = self.tLast + self.dt + self.substeps = [self.t for i in range(self.nStages)] # Manuel is ignoring different time step levels for now + #print("Hi, This is Arnob") + + + def initialize_dt(self, t0, tOut, q): + """ + Modify self.dt + """ + self.tLast = t0 + self.choose_dt() + self.t = t0 + self.dt + + def setCoefficients(self): + """ + beta are all 1's here + mwf not used right now + """ + self.alpha = np.zeros((self.nStages, self.nStages), 'd') + self.dcoefs = np.zeros((self.nStages), 'd') + + def updateStage(self): + """ + Need to switch to use coefficients + """ + self.lstage += 1 + assert self.timeOrder in [1, 2, 3] + assert self.lstage > 0 and self.lstage <= self.timeOrder + if self.timeOrder == 3: + if self.lstage == 1: + logEvent("First stage of SSP33 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + # update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] + elif self.lstage == 2: + logEvent("Second stage of SSP33 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + self.u_dof_stage[ci][self.lstage] *= old_div(1., 4.) + self.u_dof_stage[ci][self.lstage] += 3. / 4. * self.u_dof_last[ci] + # Update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] + elif self.lstage == 3: + logEvent("Third stage of SSP33 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + self.u_dof_stage[ci][self.lstage] *= old_div(2.0, 3.0) + self.u_dof_stage[ci][self.lstage] += 1.0 / 3.0 * self.u_dof_last[ci] + # update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_last[ci] + # update solution to u[0].dof + self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] + elif self.timeOrder == 2: + if self.lstage == 1: + logEvent("First stage of SSP22 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + # Update u_dof_old + self.transport.u_dof_old[:] = self.transport.u[ci].dof + elif self.lstage == 2: + logEvent("Second stage of SSP22 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + self.u_dof_stage[ci][self.lstage][:] *= old_div(1., 2.) + self.u_dof_stage[ci][self.lstage][:] += 1. / 2. * self.u_dof_last[ci] + # update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_last[ci] + # update solution to u[0].dof + self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] + else: + assert self.timeOrder == 1 + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof[:] + self.transport.u_dof_old[:] = self.transport.u[ci].dof + #self.print("Hi, Arnob") + + def initializeTimeHistory(self, resetFromDOF=True): + """ + Push necessary information into time history arrays + """ + for ci in range(self.nc): + self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] + for k in range(self.nStages): + self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] + + def updateTimeHistory(self, resetFromDOF=False): + """ + assumes successful step has been taken + """ + + self.t = self.tLast + self.dt + for ci in range(self.nc): + self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] + for k in range(self.nStages): + self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] + self.lstage = 0 + self.dtLast = self.dt + self.tLast = self.t + + def generateSubsteps(self, tList): + """ + create list of substeps over time values given in tList. These correspond to stages + """ + self.substeps = [] + tLast = self.tLast + for t in tList: + dttmp = t - tLast + self.substeps.extend([tLast + dttmp for i in range(self.nStages)]) + tLast = t + + def resetOrder(self, order): + """ + initialize data structures for stage updges + """ + self.timeOrder = order # order of approximation + self.nStages = order # number of stages total + self.lstage = 0 # last stage completed + # storage vectors + # per component stage values, list with array at each stage + self.u_dof_stage = {} + for ci in range(self.nc): + if ('m', ci) in self.transport.q: + self.u_dof_stage[ci] = [] + for k in range(self.nStages + 1): + self.u_dof_stage[ci].append(self.transport.u[ci].dof.copy()) + self.substeps = [self.t for i in range(self.nStages)] + + def setFromOptions(self, nOptions): + """ + allow classes to set various numerical parameters + """ + if 'runCFL' in dir(nOptions): + self.runCFL = nOptions.runCFL + flags = ['timeOrder'] + for flag in flags: + if flag in dir(nOptions): + val = getattr(nOptions, flag) + setattr(self, flag, val) + if flag == 'timeOrder': + self.resetOrder(self.timeOrder) + + + +class Coefficients(proteus.TransportCoefficients.TC_base): + """ + version of Re where element material type id's used in evals + """ + from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2 + from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchten_sd_het + def __init__(self, + nd, + Ksw_types, + vgm_n_types, + vgm_alpha_types, + thetaR_types, + thetaSR_types, + gravity, + density, + beta, + diagonal_conductivity=True, + getSeepageFace=None, + # FOR EDGE BASED EV + STABILIZATION_TYPE=0, + ENTROPY_TYPE=2, # logarithmic + LUMPED_MASS_MATRIX=False, + MONOLITHIC=True, + FCT=True, + num_fct_iter=1, + # FOR ENTROPY VISCOSITY + cE=1.0, + uL=0.0, + uR=1.0, + # FOR ARTIFICIAL COMPRESSION + cK=1.0, + # OUTPUT quantDOFs + outputQuantDOFs=False, ): + self.anb_seepage_flux= 0.00 + #self.anb_seepage_flux_n =0.0 + variableNames=['pressure_head'] + nc=1 + mass={0:{0:'nonlinear'}} + advection={0:{0:'nonlinear'}} + diffusion={0:{0:{0:'nonlinear'}}} + potential={0:{0:'u'}} + reaction={0:{0:'linear'}} + hamiltonian={} + self.getSeepageFace=getSeepageFace + self.gravity=gravity + self.rho = density + self.beta=beta + self.vgm_n_types = vgm_n_types + self.vgm_alpha_types = vgm_alpha_types + self.thetaR_types = thetaR_types + self.thetaSR_types = thetaSR_types + self.elementMaterialTypes = None + self.exteriorElementBoundaryTypes = None + self.materialTypes_q = None + self.materialTypes_ebq = None + self.materialTypes_ebqe = None + self.nd = nd + self.nMaterialTypes = len(thetaR_types) + self.q = {}; self.ebqe = {}; self.ebq = {}; self.ebq_global={} + #try to allow some flexibility in input of permeability/conductivity tensor + self.diagonal_conductivity = diagonal_conductivity + self.Ksw_types_in = Ksw_types + if self.diagonal_conductivity: + sparseDiffusionTensors = {(0,0):(np.arange(self.nd+1,dtype='i'), + np.arange(self.nd,dtype='i'))} + + assert len(Ksw_types.shape) in [1,2], "if diagonal conductivity true then Ksw_types scalar or vector of diagonal entries" + #allow scalar input Ks + if len(Ksw_types.shape)==1: + self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd),'d') + for I in range(self.nd): + self.Ksw_types[:,I] = Ksw_types + else: + self.Ksw_types = Ksw_types + else: #full + sparseDiffusionTensors = {(0,0):(np.arange(self.nd**2+1,step=self.nd,dtype='i'), + np.array([list(range(self.nd)) for row in range(self.nd)],dtype='i'))} + assert len(Ksw_types.shape) in [1,2], "if full tensor conductivity true then Ksw_types scalar or 'flattened' row-major representation of entries" + if len(Ksw_types.shape)==1: + self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd**2),'d') + for I in range(self.nd): + self.Ksw_types[:,I*self.nd+I] = Ksw_types + else: + assert Ksw_types.shape[1] == self.nd**2 + self.Ksw_types = Ksw_types + # EDGE BASED (AND ENTROPY) VISCOSITY + self.LUMPED_MASS_MATRIX = LUMPED_MASS_MATRIX + self.MONOLITHIC = MONOLITHIC + self.STABILIZATION_TYPE = STABILIZATION_TYPE + self.ENTROPY_TYPE = ENTROPY_TYPE + self.FCT = FCT + self.num_fct_iter=num_fct_iter + self.uL = uL + self.uR = uR + self.cK = cK + self.forceStrongConditions = True + self.cE = cE + self.outputQuantDOFs = outputQuantDOFs + TC_base.__init__(self, + nc, + mass, + advection, + diffusion, + potential, + reaction, + hamiltonian, + variableNames, + sparseDiffusionTensors = sparseDiffusionTensors, + useSparseDiffusion = True) + + def initializeMesh(self,mesh): + from proteus.SubsurfaceTransportCoefficients import BlockHeterogeneousCoefficients + self.elementMaterialTypes,self.exteriorElementBoundaryTypes,self.elementBoundaryTypes = BlockHeterogeneousCoefficients(mesh).initializeMaterialTypes() + #want element boundary material types for evaluating heterogeneity + #not boundary conditions + self.isSeepageFace = np.zeros((mesh.nExteriorElementBoundaries_global),'i') + if self.getSeepageFace != None: + for ebNE in range(mesh.nExteriorElementBoundaries_global): + #mwf missing ebNE-->ebN? + ebN = mesh.exteriorElementBoundariesArray[ebNE] + #print "eb flag",mesh.elementBoundaryMaterialTypes[ebN] + #print("Hi, Arnob") + #print self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) + self.isSeepageFace[ebNE] = self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) + #print (self.isSeepageFace) + def initializeElementQuadrature(self,t,cq): + self.materialTypes_q = self.elementMaterialTypes + self.q_shape = cq[('u',0)].shape + #self.anb_seepage_flux= anb_seepage_flux + #print("The seepage is ", anb_seepage_flux) +# cq['Ks'] = np.zeros(self.q_shape,'d') +# for k in range(self.q_shape[1]): +# cq['Ks'][:,k] = self.Ksw_types[self.elementMaterialTypes,0] + self.q[('vol_frac',0)] = np.zeros(self.q_shape,'d') + def initializeElementBoundaryQuadrature(self,t,cebq,cebq_global): + self.materialTypes_ebq = np.zeros(cebq[('u',0)].shape[0:2],'i') + self.ebq_shape = cebq[('u',0)].shape + for ebN_local in range(self.ebq_shape[1]): + self.materialTypes_ebq[:,ebN_local] = self.elementMaterialTypes + self.ebq[('vol_frac',0)] = np.zeros(self.ebq_shape,'d') + + def initializeGlobalExteriorElementBoundaryQuadrature(self,t,cebqe): + self.materialTypes_ebqe = self.exteriorElementBoundaryTypes + self.ebqe_shape = cebqe[('u',0)].shape + self.ebqe[('vol_frac',0)] = np.zeros(self.ebqe_shape,'d') + # + + + def evaluate(self,t,c): + if c[('u',0)].shape == self.q_shape: + materialTypes = self.materialTypes_q + vol_frac = self.q[('vol_frac',0)] + elif c[('u',0)].shape == self.ebqe_shape: + materialTypes = self.materialTypes_ebqe + vol_frac = self.ebqe[('vol_frac',0)] + elif c[('u',0)].shape == self.ebq_shape: + materialTypes = self.materialTypes_ebq + vol_frac = self.ebq[('vol_frac',0)] + else: + assert False, "no materialType found to match c[('u',0)].shape= %s " % c[('u',0)].shape + self.conservativeHeadRichardsMualemVanGenuchten_sd_het(self.sdInfo[(0,0)][0], + self.sdInfo[(0,0)][1], + materialTypes, + self.rho, + self.beta, + self.gravity, + self.vgm_alpha_types, + self.vgm_n_types, + self.thetaR_types, + self.thetaSR_types, + self.Ksw_types, + c[('u',0)], + c[('m',0)], + c[('dm',0,0)], + c[('f',0)], + c[('df',0,0)], + c[('a',0,0)], + c[('da',0,0,0)], + vol_frac) + # print "Picard---------------------------------------------------------------" + # c[('df',0,0)][:] = 0.0 + # c[('da',0,0,0)][:] = 0.0 +# self.conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2(materialTypes, +# self.rho, +# self.beta, +# self.gravity, +# self.vgm_alpha_types, +# self.vgm_n_types, +# self.thetaR_types, +# self.thetaSR_types, +# self.Ksw_types, +# c[('u',0)], +# c[('m',0)], +# c[('dm',0,0)], +# c[('f',0)], +# c[('df',0,0)], +# c[('a',0,0)], +# c[('da',0,0,0)]) + #mwf debug + if (np.isnan(c[('da',0,0,0)]).any() or + np.isnan(c[('a',0,0)]).any() or + np.isnan(c[('df',0,0)]).any() or + np.isnan(c[('f',0)]).any() or + np.isnan(c[('u',0)]).any() or + np.isnan(c[('m',0)]).any() or + np.isnan(c[('dm',0,0)]).any()): + import pdb + pdb.set_trace() + + def postStep(self, t, firstStep=False): + # #anb_seepage_flux_n[:]= self.anb_seepage_flux + with open('seepage_stab_0', "a") as f: + # f.write("\n Time"+ ",\t" +"Seepage\n") + f.write(repr(t)+ ",\t")# +repr(np.sum(self.LevelModel.anb_seepage_flux_n))) + +class LevelModel(proteus.Transport.OneLevelTransport): + nCalls=0 + def __init__(self, + uDict, + phiDict, + testSpaceDict, + matType, + dofBoundaryConditionsDict, + dofBoundaryConditionsSetterDict, + coefficients, + elementQuadrature, + elementBoundaryQuadrature, + fluxBoundaryConditionsDict=None, + advectiveFluxBoundaryConditionsSetterDict=None, + diffusiveFluxBoundaryConditionsSetterDictDict=None, + stressTraceBoundaryConditionsSetterDict=None, + stabilization=None, + shockCapturing=None, + conservativeFluxDict=None, + numericalFluxType=None, + TimeIntegrationClass=None, + massLumping=False, + reactionLumping=False, + options=None, + name='defaultName', + reuse_trial_and_test_quadrature=True, + sd = True, + movingDomain=False, + bdyNullSpace=False): + self.bdyNullSpace=bdyNullSpace + # + #set the objects describing the method and boundary conditions + # + self.movingDomain=movingDomain + self.tLast_mesh=None + # + self.name=name + self.sd=sd + self.Hess=False + self.lowmem=True + self.timeTerm=True#allow turning off the time derivative + #self.lowmem=False + self.testIsTrial=True + self.phiTrialIsTrial=True + self.u = uDict + self.ua = {}#analytical solutions + self.phi = phiDict + self.dphi={} + self.matType = matType + #mwf try to reuse test and trial information across components if spaces are the same + self.reuse_test_trial_quadrature = reuse_trial_and_test_quadrature#True#False + if self.reuse_test_trial_quadrature: + for ci in range(1,coefficients.nc): + assert self.u[ci].femSpace.__class__.__name__ == self.u[0].femSpace.__class__.__name__, "to reuse_test_trial_quad all femSpaces must be the same!" + self.u_dof_old = None + ## Simplicial Mesh + self.mesh = self.u[0].femSpace.mesh #assume the same mesh for all components for now + self.testSpace = testSpaceDict + self.dirichletConditions = dofBoundaryConditionsDict + self.dirichletNodeSetList=None #explicit Dirichlet conditions for now, no Dirichlet BC constraints + self.coefficients = coefficients + self.coefficients.initializeMesh(self.mesh) + self.nc = self.coefficients.nc + self.stabilization = stabilization + self.shockCapturing = shockCapturing + self.conservativeFlux = conservativeFluxDict #no velocity post-processing for now + self.fluxBoundaryConditions=fluxBoundaryConditionsDict + self.advectiveFluxBoundaryConditionsSetterDict=advectiveFluxBoundaryConditionsSetterDict + self.diffusiveFluxBoundaryConditionsSetterDictDict = diffusiveFluxBoundaryConditionsSetterDictDict + #determine whether the stabilization term is nonlinear + self.stabilizationIsNonlinear = False + #cek come back + if self.stabilization != None: + for ci in range(self.nc): + if ci in coefficients.mass: + for flag in list(coefficients.mass[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.advection: + for flag in list(coefficients.advection[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.diffusion: + for diffusionDict in list(coefficients.diffusion[ci].values()): + for flag in list(diffusionDict.values()): + if flag != 'constant': + self.stabilizationIsNonlinear=True + if ci in coefficients.potential: + for flag in list(coefficients.potential[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.reaction: + for flag in list(coefficients.reaction[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.hamiltonian: + for flag in list(coefficients.hamiltonian[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + #determine if we need element boundary storage + self.elementBoundaryIntegrals = {} + for ci in range(self.nc): + self.elementBoundaryIntegrals[ci] = ((self.conservativeFlux != None) or + (numericalFluxType != None) or + (self.fluxBoundaryConditions[ci] == 'outFlow') or + (self.fluxBoundaryConditions[ci] == 'mixedFlow') or + (self.fluxBoundaryConditions[ci] == 'setFlow')) + # + #calculate some dimensions + # + self.nSpace_global = self.u[0].femSpace.nSpace_global #assume same space dim for all variables + self.nDOF_trial_element = [u_j.femSpace.max_nDOF_element for u_j in list(self.u.values())] + self.nDOF_phi_trial_element = [phi_k.femSpace.max_nDOF_element for phi_k in list(self.phi.values())] + self.n_phi_ip_element = [phi_k.femSpace.referenceFiniteElement.interpolationConditions.nQuadraturePoints for phi_k in list(self.phi.values())] + self.nDOF_test_element = [femSpace.max_nDOF_element for femSpace in list(self.testSpace.values())] + self.nFreeDOF_global = [dc.nFreeDOF_global for dc in list(self.dirichletConditions.values())] + self.nVDOF_element = sum(self.nDOF_trial_element) + self.nFreeVDOF_global = sum(self.nFreeDOF_global) + # + NonlinearEquation.__init__(self,self.nFreeVDOF_global) + # + #build the quadrature point dictionaries from the input (this + #is just for convenience so that the input doesn't have to be + #complete) + # + elementQuadratureDict={} + elemQuadIsDict = isinstance(elementQuadrature,dict) + if elemQuadIsDict: #set terms manually + for I in self.coefficients.elementIntegralKeys: + if I in elementQuadrature: + elementQuadratureDict[I] = elementQuadrature[I] + + else: + elementQuadratureDict[I] = elementQuadrature['default'] + else: + for I in self.coefficients.elementIntegralKeys: + elementQuadratureDict[I] = elementQuadrature + if self.stabilization != None: + for I in self.coefficients.elementIntegralKeys: + if elemQuadIsDict: + if I in elementQuadrature: + elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature[I] + else: + elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature['default'] + else: + elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature + if self.shockCapturing != None: + for ci in self.shockCapturing.components: + if elemQuadIsDict: + if ('numDiff',ci,ci) in elementQuadrature: + elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature[('numDiff',ci,ci)] + #print("Hi, Arnob1") + #print(anb_seepage_flux) + else: + elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature['default'] + #print("Hi, Arnob2") + #print(anb_seepage_flux) + else: + elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature + print("Hi, Arnob3") + #print(anb_seepage_flux) + if massLumping: + for ci in list(self.coefficients.mass.keys()): + elementQuadratureDict[('m',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + print("Hi, Arnob4") + #print(anb_seepage_flux) + for I in self.coefficients.elementIntegralKeys: + elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + print("Hi, Arnob5") + #print(anb_seepage_flux) + if reactionLumping: + for ci in list(self.coefficients.mass.keys()): + elementQuadratureDict[('r',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + print("Hi, Arnob6") + #print(anb_seepage_flux) + for I in self.coefficients.elementIntegralKeys: + elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + print("Hi, Arnob7") + #print(anb_seepage_flux) + elementBoundaryQuadratureDict={} + if isinstance(elementBoundaryQuadrature,dict): #set terms manually + for I in self.coefficients.elementBoundaryIntegralKeys: + if I in elementBoundaryQuadrature: + elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature[I] + print("Hi, Arnob8") + #print(anb_seepage_flux) + else: + elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature['default'] + #print("Hi, Arnob9") + #print(anb_seepage_flux) + else: + for I in self.coefficients.elementBoundaryIntegralKeys: + elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature + print("Hi, Arnob10") + #print(anb_seepage_flux) + # + # find the union of all element quadrature points and + # build a quadrature rule for each integral that has a + # weight at each point in the union + #mwf include tag telling me which indices are which quadrature rule? + (self.elementQuadraturePoints,self.elementQuadratureWeights, + self.elementQuadratureRuleIndeces) = Quadrature.buildUnion(elementQuadratureDict) + self.nQuadraturePoints_element = self.elementQuadraturePoints.shape[0] + self.nQuadraturePoints_global = self.nQuadraturePoints_element*self.mesh.nElements_global + # + #Repeat the same thing for the element boundary quadrature + # + (self.elementBoundaryQuadraturePoints, + self.elementBoundaryQuadratureWeights, + self.elementBoundaryQuadratureRuleIndeces) = Quadrature.buildUnion(elementBoundaryQuadratureDict) + self.nElementBoundaryQuadraturePoints_elementBoundary = self.elementBoundaryQuadraturePoints.shape[0] + self.nElementBoundaryQuadraturePoints_global = (self.mesh.nElements_global* + self.mesh.nElementBoundaries_element* + self.nElementBoundaryQuadraturePoints_elementBoundary) +# if isinstance(self.u[0].femSpace,C0_AffineLinearOnSimplexWithNodalBasis): +# print self.nQuadraturePoints_element +# if self.nSpace_global == 3: +# assert(self.nQuadraturePoints_element == 5) +# elif self.nSpace_global == 2: +# assert(self.nQuadraturePoints_element == 6) +# elif self.nSpace_global == 1: +# assert(self.nQuadraturePoints_element == 3) +# +# print self.nElementBoundaryQuadraturePoints_elementBoundary +# if self.nSpace_global == 3: +# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) +# elif self.nSpace_global == 2: +# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) +# elif self.nSpace_global == 1: +# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 1) + + # + #storage dictionaries + self.scalars_element = set() + # + #simplified allocations for test==trial and also check if space is mixed or not + # + self.q={} + self.ebq={} + self.ebq_global={} + self.ebqe={} + self.phi_ip={} + self.edge_based_cfl = np.zeros(self.u[0].dof.shape)+100 + #mesh + #self.q['x'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,3),'d') + self.q[('dV_u', 0)] = (old_div(1.0, self.mesh.nElements_global)) * np.ones((self.mesh.nElements_global, self.nQuadraturePoints_element), 'd') + self.ebqe['x'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,3),'d') + self.q[('u',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') + self.q[('grad(u)',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') + self.q['velocity'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') + self.q[('m',0)] = self.q[('u',0)].copy() + self.q[('mt',0)] = self.q[('u',0)].copy() + self.q[('m_last',0)] = self.q[('u',0)].copy() + self.q[('m_tmp',0)] = self.q[('u',0)].copy() + self.q[('cfl',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') + self.q[('numDiff',0,0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') + self.ebqe[('u',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.ebqe[('grad(u)',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') + self.ebqe['velocity'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') + self.ebqe[('advectiveFlux_bc_flag',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'i') + self.ebqe[('advectiveFlux_bc',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.ebqe[('advectiveFlux',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.ebqe[('penalty')] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.points_elementBoundaryQuadrature= set() + self.scalars_elementBoundaryQuadrature= set([('u',ci) for ci in range(self.nc)]) + self.vectors_elementBoundaryQuadrature= set() + self.tensors_elementBoundaryQuadrature= set() + self.inflowBoundaryBC = {} + self.inflowBoundaryBC_values = {} + self.inflowFlux = {} + for cj in range(self.nc): + self.inflowBoundaryBC[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,),'i') + self.inflowBoundaryBC_values[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nDOF_trial_element[cj]),'d') + self.inflowFlux[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.internalNodes = set(range(self.mesh.nNodes_global)) + #identify the internal nodes this is ought to be in mesh + ##\todo move this to mesh + for ebNE in range(self.mesh.nExteriorElementBoundaries_global): + ebN = self.mesh.exteriorElementBoundariesArray[ebNE] + eN_global = self.mesh.elementBoundaryElementsArray[ebN,0] + ebN_element = self.mesh.elementBoundaryLocalElementBoundariesArray[ebN,0] + for i in range(self.mesh.nNodes_element): + if i != ebN_element: + I = self.mesh.elementNodesArray[eN_global,i] + self.internalNodes -= set([I]) + self.nNodes_internal = len(self.internalNodes) + self.internalNodesArray=np.zeros((self.nNodes_internal,),'i') + for nI,n in enumerate(self.internalNodes): + self.internalNodesArray[nI]=n + # + del self.internalNodes + self.internalNodes = None + logEvent("Updating local to global mappings",2) + self.updateLocal2Global() + logEvent("Building time integration object",2) + logEvent(memory("inflowBC, internalNodes,updateLocal2Global","OneLevelTransport"),level=4) + #mwf for interpolating subgrid error for gradients etc + if self.stabilization and self.stabilization.usesGradientStabilization: + self.timeIntegration = TimeIntegrationClass(self,integrateInterpolationPoints=True) + else: + self.timeIntegration = TimeIntegrationClass(self) + + if options != None: + self.timeIntegration.setFromOptions(options) + logEvent(memory("TimeIntegration","OneLevelTransport"),level=4) + logEvent("Calculating numerical quadrature formulas",2) + self.calculateQuadrature() + #lay out components/equations contiguously for now + self.offset = [0] + for ci in range(1,self.nc): + self.offset += [self.offset[ci-1]+self.nFreeDOF_global[ci-1]] + self.stride = [1 for ci in range(self.nc)] + #use contiguous layout of components for parallel, requires weak DBC's + # mql. Some ASSERTS to restrict the combination of the methods + if self.coefficients.STABILIZATION_TYPE > 0: + pass + #assert self.timeIntegration.isSSP == True, "If STABILIZATION_TYPE>0, use RKEV timeIntegration within VOF model" + #cond = 'levelNonlinearSolver' in dir(options) and (options.levelNonlinearSolver == + # ExplicitLumpedMassMatrixForRichards or options.levelNonlinearSolver == ExplicitConsistentMassMatrixForRichards) + #assert cond, "If STABILIZATION_TYPE>0, use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards or ExplicitConsistentMassMatrixForRichards" + try: + if 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards: + assert self.coefficients.LUMPED_MASS_MATRIX, "If levelNonlinearSolver=ExplicitLumpedMassMatrix, use LUMPED_MASS_MATRIX=True" + except: + pass + if self.coefficients.LUMPED_MASS_MATRIX == True: + cond = self.coefficients.STABILIZATION_TYPE == 2 + assert cond, "Use lumped mass matrix just with: STABILIZATION_TYPE=2 (smoothness based stab.)" + cond = 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards + assert cond, "Use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards when the mass matrix is lumped" + if self.coefficients.FCT == True: + cond = self.coefficients.STABILIZATION_TYPE > 0, "Use FCT just with STABILIZATION_TYPE>0; i.e., edge based stabilization" + # END OF ASSERTS + + # cek adding empty data member for low order numerical viscosity structures here for now + self.ML = None # lumped mass matrix + self.MC_global = None # consistent mass matrix + self.cterm_global = None + self.cterm_transpose_global = None + # dL_global and dC_global are not the full matrices but just the CSR arrays containing the non zero entries + self.residualComputed=False #TMP + self.dLow= None + self.fluxMatrix = None + self.uDotLow = None + self.uLow = None + self.dt_times_dC_minus_dL = None + self.min_s_bc = None + self.max_s_bc = None + # Aux quantity at DOFs to be filled by optimized code (MQL) + self.quantDOFs = np.zeros(self.u[0].dof.shape, 'd') + self.sLow = np.zeros(self.u[0].dof.shape, 'd') + self.sHigh = np.zeros(self.u[0].dof.shape, 'd') + self.sn = np.zeros(self.u[0].dof.shape, 'd') + self.anb_seepage_flux_n = np.zeros(self.u[0].dof.shape, 'd') + comm = Comm.get() + self.comm=comm + if comm.size() > 1: + assert numericalFluxType != None and numericalFluxType.useWeakDirichletConditions,"You must use a numerical flux to apply weak boundary conditions for parallel runs" + self.offset = [0] + for ci in range(1,self.nc): + self.offset += [ci] + self.stride = [self.nc for ci in range(self.nc)] + # + logEvent(memory("stride+offset","OneLevelTransport"),level=4) + + + if numericalFluxType != None: + if options is None or options.periodicDirichletConditions is None: + self.numericalFlux = numericalFluxType(self, + dofBoundaryConditionsSetterDict, + advectiveFluxBoundaryConditionsSetterDict, + diffusiveFluxBoundaryConditionsSetterDictDict) + else: + self.numericalFlux = numericalFluxType(self, + dofBoundaryConditionsSetterDict, + advectiveFluxBoundaryConditionsSetterDict, + diffusiveFluxBoundaryConditionsSetterDictDict, + options.periodicDirichletConditions) + else: + self.numericalFlux = None + #set penalty terms + #cek todo move into numerical flux initialization + if 'penalty' in self.ebq_global: + for ebN in range(self.mesh.nElementBoundaries_global): + for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): + self.ebq_global['penalty'][ebN,k] = old_div(self.numericalFlux.penalty_constant,(self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power)) + #penalty term + #cek move to Numerical flux initialization + if 'penalty' in self.ebqe: + for ebNE in range(self.mesh.nExteriorElementBoundaries_global): + ebN = self.mesh.exteriorElementBoundariesArray[ebNE] + for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): + self.ebqe['penalty'][ebNE,k] = old_div(self.numericalFlux.penalty_constant,self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power) + logEvent(memory("numericalFlux","OneLevelTransport"),level=4) + self.elementEffectiveDiametersArray = self.mesh.elementInnerDiametersArray + #use post processing tools to get conservative fluxes, None by default + from proteus import PostProcessingTools + self.velocityPostProcessor = PostProcessingTools.VelocityPostProcessingChooser(self) + logEvent(memory("velocity postprocessor","OneLevelTransport"),level=4) + #helper for writing out data storage + from proteus import Archiver + self.elementQuadratureDictionaryWriter = Archiver.XdmfWriter() + self.elementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() + self.exteriorElementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() + #TODO get rid of this + for ci,fbcObject in list(self.fluxBoundaryConditionsObjectsDict.items()): + self.ebqe[('advectiveFlux_bc_flag',ci)] = np.zeros(self.ebqe[('advectiveFlux_bc',ci)].shape,'i') + for t,g in list(fbcObject.advectiveFluxBoundaryConditionsDict.items()): + if ci in self.coefficients.advection: + self.ebqe[('advectiveFlux_bc',ci)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) + self.ebqe[('advectiveFlux_bc_flag',ci)][t[0],t[1]] = 1 + + if hasattr(self.numericalFlux,'setDirichletValues'): + self.numericalFlux.setDirichletValues(self.ebqe) + if not hasattr(self.numericalFlux,'isDOFBoundary'): + self.numericalFlux.isDOFBoundary = {0:np.zeros(self.ebqe[('u',0)].shape,'i')} + if not hasattr(self.numericalFlux,'ebqe'): + self.numericalFlux.ebqe = {('u',0):np.zeros(self.ebqe[('u',0)].shape,'d')} + #TODO how to handle redistancing calls for calculateCoefficients,calculateElementResidual etc + self.globalResidualDummy = None + compKernelFlag=0 + self.delta_x_ij=None + self.richards = cRichards_base(self.nSpace_global, + self.nQuadraturePoints_element, + self.u[0].femSpace.elementMaps.localFunctionSpace.dim, + self.u[0].femSpace.referenceFiniteElement.localFunctionSpace.dim, + self.testSpace[0].referenceFiniteElement.localFunctionSpace.dim, + self.nElementBoundaryQuadraturePoints_elementBoundary, + compKernelFlag) + if self.movingDomain: + self.MOVING_DOMAIN=1.0 + else: + self.MOVING_DOMAIN=0.0 + #cek hack + self.movingDomain=False + self.MOVING_DOMAIN=0.0 + if self.mesh.nodeVelocityArray is None: + self.mesh.nodeVelocityArray = np.zeros(self.mesh.nodeArray.shape,'d') + self.forceStrongConditions=True + self.dirichletConditionsForceDOF = {} + if self.forceStrongConditions: + for cj in range(self.nc): + self.dirichletConditionsForceDOF[cj] = DOFBoundaryConditions(self.u[cj].femSpace,dofBoundaryConditionsSetterDict[cj],weakDirichletConditions=False) + def FCTStep(self): + import pdb + rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() + limited_solution = np.zeros((len(rowptr) - 1),'d') + #self.u_free_dof_stage_0_l = np.zeros((len(rowptr) - 1),'d') + #self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage], # soln + #fromFreeToGlobal=0 + #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + # self.offset[0], + # self.stride[0], + # self.dirichletConditions[0].global2freeGlobal_global_dofs, + # self.dirichletConditions[0].global2freeGlobal_free_dofs, + # self.u_free_dof_stage_0_l, + # self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage]) + argsDict = cArgumentsDict.ArgumentsDict() + argsDict["bc_mask"] = self.bc_mask + argsDict["NNZ"] = self.nnz + argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs + argsDict["dt"] = self.timeIntegration.dt + argsDict["lumped_mass_matrix"] = self.ML + argsDict["soln"] = self.sn + argsDict["pn"] = self.u[0].dof + argsDict["solH"] = self.sHigh + argsDict["uLow"] = self.sLow + argsDict["uDotLow"] = self.uDotLow + argsDict["limited_solution"] = limited_solution + argsDict["csrRowIndeces_DofLoops"] = rowptr + argsDict["csrColumnOffsets_DofLoops"] = colind + argsDict["MassMatrix"] = MassMatrix + argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL + argsDict["min_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0]) #cek hack just set from physical bounds + argsDict["max_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0] + self.coefficients.thetaSR_types[0]) #cek hack + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["MONOLITHIC"] =0#cek hack self.coefficients.MONOLITHIC + argsDict["anb_seepage_flux_n"]= self.anb_seepage_flux_n + #pdb.set_trace() + self.richards.FCTStep(argsDict) + + # self.nnz, # number of non zero entries + # len(rowptr) - 1, # number of DOFs + # self.timeIntegration.dt, + # self.ML, # Lumped mass matrix + # self.sn, + # self.u_dof_old, + # self.sHigh, # high order solution + # self.sLow, + # limited_solution, + # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) + # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) + # MassMatrix, + # self.dt_times_dC_minus_dL, + # self.min_s_bc, + # self.max_s_bc, + # self.coefficients.LUMPED_MASS_MATRIX, + # self.coefficients.MONOLITHIC) + old_dof = self.u[0].dof.copy() + self.invert(limited_solution, self.u[0].dof) + self.timeIntegration.u[:] = self.u[0].dof + #fromFreeToGlobal=1 #direction copying + #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + # self.offset[0], + # self.stride[0], + # self.dirichletConditions[0].global2freeGlobal_global_dofs, + # self.dirichletConditions[0].global2freeGlobal_free_dofs, + # self.u[0].dof, + # limited_solution) + def kth_FCT_step(self): + #import pdb + #pdb.set_trace() + rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() + limitedFlux = np.zeros(self.nnz) + limited_solution = np.zeros((len(rowptr) - 1),'d') + #limited_solution[:] = self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage] + fromFreeToGlobal=0 #direction copying + cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + self.offset[0], + self.stride[0], + self.dirichletConditions[0].global2freeGlobal_global_dofs, + self.dirichletConditions[0].global2freeGlobal_free_dofs, + limited_solution, + self.timeintegration.u_dof_stage[0][self.timeIntegration.lstage]) + + self.richards.kth_FCT_step( + self.timeIntegration.dt, + self.coefficients.num_fct_iter, + self.nnz, # number of non zero entries + len(rowptr) - 1, # number of DOFs + MassMatrix, + self.ML, # Lumped mass matrix + self.u_dof_old, + limited_solution, + self.uDotLow, + self.uLow, + self.dLow, + self.fluxMatrix, + limitedFlux, + rowptr, + colind) + + self.timeIntegration.u[:] = limited_solution + #self.u[0].dof[:] = limited_solution + fromFreeToGlobal=1 #direction copying + cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + self.offset[0], + self.stride[0], + self.dirichletConditions[0].global2freeGlobal_global_dofs, + self.dirichletConditions[0].global2freeGlobal_free_dofs, + self.u[0].dof, + limited_solution) + def calculateCoefficients(self): + pass + def calculateElementResidual(self): + if self.globalResidualDummy != None: + self.getResidual(self.u[0].dof,self.globalResidualDummy) + def getResidual(self,u,r): + import pdb + import copy + """ + Calculate the element residuals and add in to the global residual + """ + cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, + self.jacobian) + if self.u_dof_old is None: + # Pass initial condition to u_dof_old + self.u_dof_old = np.copy(self.u[0].dof) + rowptr, colind, nzval = self.jacobian.getCSRrepresentation() + nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix + r.fill(0.0) + ######################## + ### COMPUTE C MATRIX ### + ######################## + if self.cterm_global is None: + # since we only need cterm_global to persist, we can drop the other self.'s + self.cterm = {} + self.cterm_a = {} + self.cterm_global = {} + self.cterm_transpose = {} + self.cterm_a_transpose = {} + self.cterm_global_transpose = {} + rowptr, colind, nzval = self.jacobian.getCSRrepresentation() + nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix + di = self.q[('grad(u)', 0)].copy() # direction of derivative + # JACOBIANS (FOR ELEMENT TRANSFORMATION) + self.q[('J')] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nSpace_global, + self.nSpace_global), + 'd') + self.q[('inverse(J)')] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nSpace_global, + self.nSpace_global), + 'd') + self.q[('det(J)')] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element), + 'd') + self.u[0].femSpace.elementMaps.getJacobianValues(self.elementQuadraturePoints, + self.q['J'], + self.q['inverse(J)'], + self.q['det(J)']) + self.q['abs(det(J))'] = np.abs(self.q['det(J)']) + # SHAPE FUNCTIONS + self.q[('w', 0)] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nDOF_test_element[0]), + 'd') + self.q[('w*dV_m', 0)] = self.q[('w', 0)].copy() + self.u[0].femSpace.getBasisValues(self.elementQuadraturePoints, self.q[('w', 0)]) + cfemIntegrals.calculateWeightedShape(self.elementQuadratureWeights[('u', 0)], + self.q['abs(det(J))'], + self.q[('w', 0)], + self.q[('w*dV_m', 0)]) + # GRADIENT OF TEST FUNCTIONS + self.q[('grad(w)', 0)] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nDOF_test_element[0], + self.nSpace_global), + 'd') + self.u[0].femSpace.getBasisGradientValues(self.elementQuadraturePoints, + self.q['inverse(J)'], + self.q[('grad(w)', 0)]) + self.q[('grad(w)*dV_f', 0)] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nDOF_test_element[0], + self.nSpace_global), + 'd') + cfemIntegrals.calculateWeightedShapeGradients(self.elementQuadratureWeights[('u', 0)], + self.q['abs(det(J))'], + self.q[('grad(w)', 0)], + self.q[('grad(w)*dV_f', 0)]) + ########################## + ### LUMPED MASS MATRIX ### + ########################## + # assume a linear mass term + dm = np.ones(self.q[('u', 0)].shape, 'd') + elementMassMatrix = np.zeros((self.mesh.nElements_global, + self.nDOF_test_element[0], + self.nDOF_trial_element[0]), 'd') + cfemIntegrals.updateMassJacobian_weak_lowmem(dm, + self.q[('w', 0)], + self.q[('w*dV_m', 0)], + elementMassMatrix) + self.MC_a = nzval.copy() + self.MC_global = SparseMat(self.nFreeDOF_global[0], + self.nFreeDOF_global[0], + nnz, + self.MC_a, + colind, + rowptr) + cfemIntegrals.zeroJacobian_CSR(self.nnz, self.MC_global) + cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.csrRowIndeces[(0, 0)], + self.csrColumnOffsets[(0, 0)], + elementMassMatrix, + self.MC_global) + self.ML = np.zeros((self.nFreeDOF_global[0],), 'd') + for i in range(self.nFreeDOF_global[0]): + self.ML[i] = self.MC_a[rowptr[i]:rowptr[i + 1]].sum() + np.testing.assert_almost_equal(self.ML.sum(), + self.mesh.volume, + err_msg="Trace of lumped mass matrix should be the domain volume", verbose=True) + for d in range(self.nSpace_global): # spatial dimensions + # C matrices + self.cterm[d] = np.zeros((self.mesh.nElements_global, + self.nDOF_test_element[0], + self.nDOF_trial_element[0]), 'd') + self.cterm_a[d] = nzval.copy() + #self.cterm_a[d] = np.zeros(nzval.size) + self.cterm_global[d] = SparseMat(self.nFreeDOF_global[0], + self.nFreeDOF_global[0], + nnz, + self.cterm_a[d], + colind, + rowptr) + cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global[d]) + di[:] = 0.0 + di[..., d] = 1.0 + cfemIntegrals.updateHamiltonianJacobian_weak_lowmem(di, + self.q[('grad(w)*dV_f', 0)], + self.q[('w', 0)], + self.cterm[d]) # int[(di*grad(wj))*wi*dV] + cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.csrRowIndeces[(0, 0)], + self.csrColumnOffsets[(0, 0)], + self.cterm[d], + self.cterm_global[d]) + # C Transpose matrices + self.cterm_transpose[d] = np.zeros((self.mesh.nElements_global, + self.nDOF_test_element[0], + self.nDOF_trial_element[0]), 'd') + self.cterm_a_transpose[d] = nzval.copy() + self.cterm_global_transpose[d] = SparseMat(self.nFreeDOF_global[0], + self.nFreeDOF_global[0], + nnz, + self.cterm_a_transpose[d], + colind, + rowptr) + cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global_transpose[d]) + di[:] = 0.0 + di[..., d] = -1.0 + cfemIntegrals.updateAdvectionJacobian_weak_lowmem(di, + self.q[('w', 0)], + self.q[('grad(w)*dV_f', 0)], + self.cterm_transpose[d]) # -int[(-di*grad(wi))*wj*dV] + cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.csrRowIndeces[(0, 0)], + self.csrColumnOffsets[(0, 0)], + self.cterm_transpose[d], + self.cterm_global_transpose[d]) + + rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() + else: + Cy = np.zeros(Cx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() + else: + Cz = np.zeros(Cx.shape, 'd') + rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() + else: + CTy = np.zeros(CTx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() + else: + CTz = np.zeros(CTx.shape, 'd') + + # This is dummy. I just care about the csr structure of the sparse matrix + self.dLow = np.zeros(Cx.shape, 'd') + self.fluxMatrix = np.zeros(Cx.shape, 'd') + self.dt_times_dC_minus_dL = np.zeros(Cx.shape, 'd') + nFree = len(rowptr)-1 + self.min_s_bc = np.zeros(nFree, 'd') + 1E10 + self.max_s_bc = np.zeros(nFree, 'd') - 1E10 + self.uDotLow = np.zeros(nFree, 'd') + self.uLow = np.zeros(nFree, 'd') + # + # cek end computationa of cterm_global + # + # cek showing mquezada an example of using cterm_global sparse matrix + # calculation y = c*x where x==1 + # direction=0 + #rowptr, colind, c = self.cterm_global[direction].getCSRrepresentation() + #y = np.zeros((self.nFreeDOF_global[0],),'d') + #x = np.ones((self.nFreeDOF_global[0],),'d') + # ij=0 + # for i in range(self.nFreeDOF_global[0]): + # for offset in range(rowptr[i],rowptr[i+1]): + # j = colind[offset] + # y[i] += c[ij]*x[j] + # ij+=1 + #Load the unknowns into the finite element dof + self.timeIntegration.calculateCoefs() + self.timeIntegration.calculateU(u) + self.setUnknowns(self.timeIntegration.u) + #cek can put in logic to skip of BC's don't depend on t or u + #Dirichlet boundary conditions + self.numericalFlux.setDirichletValues(self.ebqe) + #flux boundary conditions + #cek hack, just using advective flux for flux BC for now + for t,g in list(self.fluxBoundaryConditionsObjectsDict[0].advectiveFluxBoundaryConditionsDict.items()): + self.ebqe[('advectiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) + self.ebqe[('advectiveFlux_bc_flag',0)][t[0],t[1]] = 1 + # for t,g in self.fluxBoundaryConditionsObjectsDict[0].diffusiveFluxBoundaryConditionsDict.iteritems(): + # self.ebqe[('diffusiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) + # self.ebqe[('diffusiveFlux_bc_flag',0)][t[0],t[1]] = 1 + #self.shockCapturing.lag=True + if self.forceStrongConditions: + self.bc_mask = np.ones_like(self.u[0].dof) + for cj in range(len(self.dirichletConditionsForceDOF)): + for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): + self.u[cj].dof[dofN] = g(self.dirichletConditionsForceDOF[cj].DOFBoundaryPointDict[dofN],self.timeIntegration.t) + self.u_dof_old[dofN] = self.u[cj].dof[dofN] + self.bc_mask[dofN] = 0.0 + degree_polynomial = 1 + try: + degree_polynomial = self.u[0].femSpace.order + except: + pass + + argsDict = cArgumentsDict.ArgumentsDict() + argsDict["bc_mask"] = self.bc_mask + argsDict["dt"] = self.timeIntegration.dt + argsDict["Theta"] = 1.0 + argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi + argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi + argsDict["mesh_dof"] = self.mesh.nodeArray + argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray + argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN + argsDict["mesh_l2g"] = self.mesh.elementNodesArray + argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] + argsDict["u_trial_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi + argsDict["u_test_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi + argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace + argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace + argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] + argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals + argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians + argsDict["nElements_global"] = self.mesh.nElements_global + argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] + argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, + argsDict["isSeepageFace"] = self.coefficients.isSeepageFace + argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] + argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] + argsDict["rho"] = self.coefficients.rho + argsDict["beta"] = self.coefficients.beta + argsDict["gravity"] = self.coefficients.gravity + argsDict["alpha"] = self.coefficients.vgm_alpha_types + argsDict["n"] = self.coefficients.vgm_n_types + argsDict["thetaR"] = self.coefficients.thetaR_types + argsDict["thetaSR"] = self.coefficients.thetaSR_types + argsDict["KWs"] = self.coefficients.Ksw_types + argsDict["useMetrics"] = 0.0 + argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf + argsDict["lag_shockCapturing"] = 0 + argsDict["shockCapturingDiffusion"] = 0.0 + argsDict["sc_uref"] = 0.0 + argsDict["sc_alpha"] = 0.0 + argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g + argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] + argsDict["elementDiameter"] = self.mesh.elementDiametersArray + argsDict["degree_polynomial"] = degree_polynomial + argsDict["u_dof"] = self.u[0].dof + argsDict["u_dof_old"] = self.u_dof_old + argsDict["velocity"] = self.q['velocity'] + argsDict["q_m"] = self.timeIntegration.m_tmp[0] + argsDict["q_u"] = self.q[('u',0)] + argsDict["q_dV"] = self.q[('dV_u',0)] + argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] + argsDict["cfl"] = self.q[('cfl',0)] + argsDict["q_numDiff_u"] = self.q[('cfl',0)] + argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] + argsDict["offset_u"] = self.offset[0] + argsDict["stride_u"] = self.stride[0] + argsDict["globalResidual"] = r + argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global + argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray + argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray + argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray + argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] + argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] + argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] + argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] + argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] + argsDict["ebqe_phi"] = self.ebqe[('u',0)] + argsDict["epsFact"] = 0.0 + argsDict["ebqe_u"] = self.ebqe[('u',0)] + argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] + argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE + # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION + argsDict["cE"] = self.coefficients.cE + argsDict["cK"] = self.coefficients.cK + # PARAMETERS FOR LOG BASED ENTROPY FUNCTION + argsDict["uL"] = self.coefficients.uL + argsDict["uR"] = self.coefficients.uR + # PARAMETERS FOR EDGE VISCOSITY + argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs + argsDict["NNZ"] = self.nnz + argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern + argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) + argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) + argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms + argsDict["globalJacobian"] = self.jacobian.getCSRrepresentation()[2] + # C matrices + argsDict["Cx"] = Cx + argsDict["Cy"] = Cy + argsDict["Cz"] = Cz + argsDict["CTx"] = CTx + argsDict["CTy"] = CTy + argsDict["CTz"] = CTz + argsDict["ML"] = self.ML + argsDict["delta_x_ij"] = self.delta_x_ij + # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE + argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE + # FLUX CORRECTED TRANSPORT + argsDict["dLow"] = self.dLow + argsDict["fluxMatrix"] = self.fluxMatrix + argsDict["uDotLow"] = self.uDotLow + argsDict["uLow"] = self.uLow + argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL + argsDict["min_s_bc"] = self.min_s_bc + argsDict["max_s_bc"] = self.max_s_bc + argsDict["quantDOFs"] = self.quantDOFs + argsDict["sLow"] = self.sLow + argsDict["sn"] = self.sn + argsDict["anb_seepage_flux_n"]= self.anb_seepage_flux_n + + argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #print(anb_seepage_flux) + #argsDict["anb_seepage_flux_n"] = self.coefficients.anb_seepage_flux_n + #if np.sum(anb_seepage_flux_n)>0: + + #logEvent("Hi, this is Arnob", self.anb_seepage_flux_n[0]) + print("Seepage Flux from Python file", np.sum(self.anb_seepage_flux_n)) + seepage_text_variable= np.sum(self.anb_seepage_flux_n) + + with open('seepage_stab_0',"a" ) as f: + #f.write("\n Time"+ ",\t" +"Seepage\n") + #f.write(repr(self.coefficients.t)+ ",\t" +repr(seepage_text_variable), "\n") + f.write(repr(seepage_text_variable)+ "\n") + if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG + self.calculateResidual = self.richards.calculateResidual + self.calculateJacobian = self.richards.calculateJacobian + else: + self.calculateResidual = self.richards.calculateResidual_entropy_viscosity + self.calculateJacobian = self.richards.calculateMassMatrix + if self.delta_x_ij is None: + self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') + self.calculateResidual(argsDict) + #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] + #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf + #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] + #self.timeIntegration.calculateElementCoefficients(self.q) + if self.forceStrongConditions:# + for cj in range(len(self.dirichletConditionsForceDOF)):# + for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): + r[self.offset[cj]+self.stride[cj]*dofN] = 0 + if self.stabilization: + self.stabilization.accumulateSubgridMassHistory(self.q) + logEvent("Global residual",level=9,data=r) + self.nonlinear_function_evaluations += 1 + if self.globalResidualDummy is None: + self.globalResidualDummy = np.zeros(r.shape,'d') + + #print("Hello from the python file", self.coefficients.anb_seepage_flux) + #logEvent("Hello from the python file", self.coefficients.anb_seepage_flux") + + + + + + def invert(self,u,r): + #u=s + #r=p + import pdb + import copy + """ + Calculate the element residuals and add in to the global residual + """ + self.sHigh[:] = u + rowptr, colind, nzval = self.jacobian.getCSRrepresentation() + nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix + r.fill(0.0) + rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() + else: + Cy = np.zeros(Cx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() + else: + Cz = np.zeros(Cx.shape, 'd') + rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() + else: + CTy = np.zeros(CTx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() + else: + CTz = np.zeros(CTx.shape, 'd') + + # This is dummy. I just care about the csr structure of the sparse matrix + nFree = len(rowptr)-1 + degree_polynomial = 1 + try: + degree_polynomial = self.u[0].femSpace.order + except: + pass + if self.delta_x_ij is None: + self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') + argsDict = cArgumentsDict.ArgumentsDict() + argsDict["dt"] = self.timeIntegration.dt + argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi + argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi + argsDict["mesh_dof"] = self.mesh.nodeArray + argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray + argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN + argsDict["mesh_l2g"] = self.mesh.elementNodesArray + argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] + argsDict["u_trial_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi + argsDict["u_test_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi + argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace + argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace + argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] + argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals + argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians + argsDict["nElements_global"] = self.mesh.nElements_global + argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] + argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, + argsDict["isSeepageFace"] = self.coefficients.isSeepageFace + argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] + argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] + argsDict["rho"] = self.coefficients.rho + argsDict["beta"] = self.coefficients.beta + argsDict["gravity"] = self.coefficients.gravity + argsDict["alpha"] = self.coefficients.vgm_alpha_types + argsDict["n"] = self.coefficients.vgm_n_types + argsDict["thetaR"] = self.coefficients.thetaR_types + argsDict["thetaSR"] = self.coefficients.thetaSR_types + argsDict["KWs"] = self.coefficients.Ksw_types + argsDict["useMetrics"] = 0.0 + argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf + argsDict["lag_shockCapturing"] = 0 + argsDict["shockCapturingDiffusion"] = 0.0 + argsDict["sc_uref"] = 0.0 + argsDict["sc_alpha"] = 0.0 + argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g + argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] + argsDict["elementDiameter"] = self.mesh.elementDiametersArray + argsDict["degree_polynomial"] = degree_polynomial + argsDict["u_dof"] = u#self.u[0].dof + argsDict["u_dof_old"] = self.u[0].dof + argsDict["velocity"] = self.q['velocity'] + argsDict["q_m"] = self.timeIntegration.m_tmp[0] + argsDict["q_u"] = self.q[('u',0)] + argsDict["q_dV"] = self.q[('dV_u',0)] + argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] + argsDict["cfl"] = self.q[('cfl',0)] + argsDict["q_numDiff_u"] = self.q[('cfl',0)] + argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] + argsDict["offset_u"] = self.offset[0] + argsDict["stride_u"] = self.stride[0] + argsDict["globalResidual"] = r + argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global + argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray + argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray + argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray + argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] + argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] + argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] + argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] + argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] + argsDict["ebqe_phi"] = self.ebqe[('u',0)] + argsDict["epsFact"] = 0.0 + argsDict["ebqe_u"] = self.ebqe[('u',0)] + argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] + argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE + # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION + argsDict["cE"] = self.coefficients.cE + argsDict["cK"] = self.coefficients.cK + # PARAMETERS FOR LOG BASED ENTROPY FUNCTION + argsDict["uL"] = self.coefficients.uL + argsDict["uR"] = self.coefficients.uR + # PARAMETERS FOR EDGE VISCOSITY + argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs + argsDict["NNZ"] = self.nnz + argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern + argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) + argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) + argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms + # C matrices + argsDict["Cx"] = Cx + argsDict["Cy"] = Cy + argsDict["Cz"] = Cz + argsDict["CTx"] = CTx + argsDict["CTy"] = CTy + argsDict["CTz"] = CTz + argsDict["ML"] = self.ML + argsDict["delta_x_ij"] = self.delta_x_ij + # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE + argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE + # FLUX CORRECTED TRANSPORT + argsDict["dLow"] = self.dLow + argsDict["fluxMatrix"] = self.fluxMatrix + argsDict["uDotLow"] = self.uDotLow + argsDict["uLow"] = self.uLow + argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL + argsDict["min_s_bc"] = self.min_s_bc + argsDict["max_s_bc"] = self.max_s_bc + argsDict["quantDOFs"] = self.quantDOFs + argsDict["sLow"] = self.sLow + argsDict["sn"] = self.sn + #Arnob trying to print flux + argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #print("Hi",anb_seepage_flux) + #print("Hi Seepage Flux", self.coefficients.anb_seepage_flux) + + self.richards.invert(argsDict) + # self.timeIntegration.dt, + # self.u[0].femSpace.elementMaps.psi, + # self.u[0].femSpace.elementMaps.grad_psi, + # self.mesh.nodeArray, + # self.mesh.nodeVelocityArray, + # self.MOVING_DOMAIN, + # self.mesh.elementNodesArray, + # self.elementQuadratureWeights[('u',0)], + # self.u[0].femSpace.psi, + # self.u[0].femSpace.grad_psi, + # self.u[0].femSpace.psi, + # self.u[0].femSpace.grad_psi, + # #element boundary + # self.u[0].femSpace.elementMaps.psi_trace, + # self.u[0].femSpace.elementMaps.grad_psi_trace, + # self.elementBoundaryQuadratureWeights[('u',0)], + # self.u[0].femSpace.psi_trace, + # self.u[0].femSpace.grad_psi_trace, + # self.u[0].femSpace.psi_trace, + # self.u[0].femSpace.grad_psi_trace, + # self.u[0].femSpace.elementMaps.boundaryNormals, + # self.u[0].femSpace.elementMaps.boundaryJacobians, + # #physics + # self.mesh.nElements_global, + # self.ebqe['penalty'],#double* ebqe_penalty_ext, + # self.mesh.elementMaterialTypes,#int* elementMaterialTypes, + # self.coefficients.isSeepageFace, + # self.coefficients.sdInfo[(0,0)][0],#int* a_rowptr, + # self.coefficients.sdInfo[(0,0)][1],#int* a_colind, + # self.coefficients.rho,#double rho, + # self.coefficients.beta,#double beta, + # self.coefficients.gravity,#double* gravity, + # self.coefficients.vgm_alpha_types,#double* alpha, + # self.coefficients.vgm_n_types,#double* n, + # self.coefficients.thetaR_types,#double* thetaR, + # self.coefficients.thetaSR_types,#double* thetaSR, + # self.coefficients.Ksw_types,#double* KWs, + # False,#self.coefficients.useMetrics, + # self.timeIntegration.alpha_bdf, + # 0,#self.shockCapturing.lag, + # 0.0,#cek hack self.shockCapturing.shockCapturingFactor, + # 0.0,#self.coefficients.sc_uref, + # 0.0,#self.coefficients.sc_beta, + # self.u[0].femSpace.dofMap.l2g, + # self.l2g[0]['freeGlobal'], + # self.mesh.elementDiametersArray, + # degree_polynomial, + # self.sHigh, + # self.u_dof_old, + # self.q['velocity'],#self.coefficients.q_v, + # self.timeIntegration.m_tmp[0], + # self.q[('u',0)], + # self.timeIntegration.beta_bdf[0], + # self.q[('cfl',0)], + # self.edge_based_cfl, + # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff[0], + # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff_last[0], + # self.offset[0],self.stride[0], + # r, + # self.mesh.nExteriorElementBoundaries_global, + # self.mesh.exteriorElementBoundariesArray, + # self.mesh.elementBoundaryElementsArray, + # self.mesh.elementBoundaryLocalElementBoundariesArray, + # self.ebqe['velocity'],#self.coefficients.ebqe_v, + # self.numericalFlux.isDOFBoundary[0], + # self.numericalFlux.ebqe[('u',0)], + # self.ebqe[('advectiveFlux_bc_flag',0)], + # self.ebqe[('advectiveFlux_bc',0)], + # self.ebqe[('u',0)],#cek hack self.coefficients.ebqe_phi, + # 0.0,#cek hack self.coefficients.epsFact, + # self.ebqe[('u',0)], + # self.ebqe[('advectiveFlux',0)], + # # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION + # self.coefficients.cE, + # self.coefficients.cK, + # # PARAMETERS FOR LOG BASED ENTROPY FUNCTION + # self.coefficients.uL, + # self.coefficients.uR, + # # PARAMETERS FOR EDGE VISCOSITY + # len(rowptr) - 1, # num of DOFs + # len(Cx), # num of non-zero entries in the sparsity pattern + # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) + # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) + # self.csrRowIndeces[(0, 0)], # row indices (convenient for element loops) + # self.csrColumnOffsets[(0, 0)], # column indices (convenient for element loops) + # self.csrColumnOffsets_eb[(0, 0)], # indices for boundary terms + # # C matrices + # Cx, + # Cy, + # Cz, + # CTx, + # CTy, + # CTz, + # self.ML, + # self.delta_x_ij, + # # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + # self.coefficients.LUMPED_MASS_MATRIX, + # self.coefficients.STABILIZATION_TYPE, + # self.coefficients.ENTROPY_TYPE, + # # FLUX CORRECTED TRANSPORT + # self.dLow, + # self.fluxMatrix, + # self.uDotLow, + # self.uLow, + # self.dt_times_dC_minus_dL, + # self.min_s_bc, + # self.max_s_bc, + # self.quantDOFs) + #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] + #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf + #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] + #self.timeIntegration.calculateElementCoefficients(self.q) + #if self.forceStrongConditions:# + # for cj in range(len(self.dirichletConditionsForceDOF)):# + # for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): + # r[self.offset[cj]+self.stride[cj]*dofN] = 0 + #if self.stabilization: + # self.stabilization.accumulateSubgridMassHistory(self.q) + #logEvent("Global residual",level=9,data=r) + #self.nonlinear_function_evaluations += 1 + #if self.globalResidualDummy is None: + # self.globalResidualDummy = numpy.zeros(r.shape,'d') + def postStep(self, t, firstStep=False): + with open('seepage_flux_nnnn', "a") as f: + f.write("\n Time"+ ",\t" +"Seepage\n") + f.write(repr(t)+ ",\t" +repr(self.coefficients.anb_seepage_flux)) + def getJacobian(self,jacobian): + if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG + cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, + jacobian) + degree_polynomial = 1 + try: + degree_polynomial = self.u[0].femSpace.order + except: + pass + if self.delta_x_ij is None: + self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') + argsDict = cArgumentsDict.ArgumentsDict() + argsDict["dt"] = self.timeIntegration.dt + argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi + argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi + argsDict["mesh_dof"] = self.mesh.nodeArray + argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray + argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN + argsDict["mesh_l2g"] = self.mesh.elementNodesArray + argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] + argsDict["u_trial_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi + argsDict["u_test_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi + argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace + argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace + argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] + argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals + argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians + argsDict["nElements_global"] = self.mesh.nElements_global + argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] + argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, + argsDict["isSeepageFace"] = self.coefficients.isSeepageFace + argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] + argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] + argsDict["rho"] = self.coefficients.rho + argsDict["beta"] = self.coefficients.beta + argsDict["gravity"] = self.coefficients.gravity + argsDict["alpha"] = self.coefficients.vgm_alpha_types + argsDict["n"] = self.coefficients.vgm_n_types + argsDict["thetaR"] = self.coefficients.thetaR_types + argsDict["thetaSR"] = self.coefficients.thetaSR_types + argsDict["KWs"] = self.coefficients.Ksw_types + argsDict["useMetrics"] = 0.0 + argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf + argsDict["lag_shockCapturing"] = 0 + argsDict["shockCapturingDiffusion"] = 0.0 + argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g + argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] + argsDict["elementDiameter"] = self.mesh.elementDiametersArray + argsDict["degree_polynomial"] = degree_polynomial + argsDict["u_dof"] = self.u[0].dof + argsDict["velocity"] = self.q['velocity'] + argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] + argsDict["cfl"] = self.q[('cfl',0)] + argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] + argsDict["csrRowIndeces_u_u"] = self.csrRowIndeces[(0,0)] + argsDict["csrColumnOffsets_u_u"] = self.csrColumnOffsets[(0,0)] + argsDict["globalJacobian"] = jacobian.getCSRrepresentation()[2] + argsDict["delta_x_ij"] = self.delta_x_ij + argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global + argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray + argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray + argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray + argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] + argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] + argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] + argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] + argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] + argsDict["csrColumnOffsets_eb_u_u"] = self.csrColumnOffsets_eb[(0,0)] + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + + #arnob trying to calculate flux + #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #Arnob trying to print flux + #argsDict["anb_seepage_flux"] = self.calculateResidual.anb_seepage_flux + + #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #print("Hi Seepage Flux", self.coefficients.anb_seepage_flux) + #print("Hi Seepage Flux",anb_seepage_flux) + #print("The seepage is ", anb_seepage_flux) + + + + + self.calculateJacobian(argsDict) + if self.forceStrongConditions: + for dofN in list(self.dirichletConditionsForceDOF[0].DOFBoundaryConditionsDict.keys()): + global_dofN = self.offset[0]+self.stride[0]*dofN + self.nzval[np.where(self.colind == global_dofN)] = 0.0 #column + self.nzval[self.rowptr[global_dofN]:self.rowptr[global_dofN+1]] = 0.0 #row + zeroRow=True + for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]):#row + if (self.colind[i] == global_dofN): + self.nzval[i] = 1.0 + zeroRow = False + if zeroRow: + raise RuntimeError("Jacobian has a zero row because sparse matrix has no diagonal entry at row "+repr(global_dofN)+". You probably need add diagonal mass or reaction term") + #scaling = 1.0#probably want to add some scaling to match non-dirichlet diagonals in linear system + #for cj in range(self.nc): + # for dofN in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.keys()): + # global_dofN = self.offset[cj]+self.stride[cj]*dofN + # for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]): + # if (self.colind[i] == global_dofN): + # self.nzval[i] = scaling + # else: + # self.nzval[i] = 0.0 + logEvent("Jacobian ",level=10,data=jacobian) + #mwf decide if this is reasonable for solver statistics + self.nonlinear_function_jacobian_evaluations += 1 + return jacobian + def calculateElementQuadrature(self): + """ + Calculate the physical location and weights of the quadrature rules + and the shape information at the quadrature points. + + This function should be called only when the mesh changes. + """ + #self.u[0].femSpace.elementMaps.getValues(self.elementQuadraturePoints, + # self.q['x']) + self.u[0].femSpace.elementMaps.getBasisValuesRef(self.elementQuadraturePoints) + self.u[0].femSpace.elementMaps.getBasisGradientValuesRef(self.elementQuadraturePoints) + self.u[0].femSpace.getBasisValuesRef(self.elementQuadraturePoints) + self.u[0].femSpace.getBasisGradientValuesRef(self.elementQuadraturePoints) + self.coefficients.initializeElementQuadrature(self.timeIntegration.t,self.q) + if self.stabilization != None: + self.stabilization.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) + self.stabilization.initializeTimeIntegration(self.timeIntegration) + if self.shockCapturing != None: + self.shockCapturing.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) + def calculateElementBoundaryQuadrature(self): + pass + def calculateExteriorElementBoundaryQuadrature(self): + """ + Calculate the physical location and weights of the quadrature rules + and the shape information at the quadrature points on global element boundaries. + + This function should be called only when the mesh changes. + """ + # + #get physical locations of element boundary quadrature points + # + #assume all components live on the same mesh + self.u[0].femSpace.elementMaps.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.elementMaps.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.elementMaps.getValuesGlobalExteriorTrace(self.elementBoundaryQuadraturePoints, + self.ebqe['x']) + self.fluxBoundaryConditionsObjectsDict = dict([(cj,FluxBoundaryConditions(self.mesh, + self.nElementBoundaryQuadraturePoints_elementBoundary, + self.ebqe[('x')], + getAdvectiveFluxBoundaryConditions=self.advectiveFluxBoundaryConditionsSetterDict[cj], + getDiffusiveFluxBoundaryConditions=self.diffusiveFluxBoundaryConditionsSetterDictDict[cj])) + for cj in list(self.advectiveFluxBoundaryConditionsSetterDict.keys())]) + self.coefficients.initializeGlobalExteriorElementBoundaryQuadrature(self.timeIntegration.t,self.ebqe) + #argsDict = cArgumentsDict.ArgumentsDict() + #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #print("Hi", self.coefficients.anb_seepage_flux) + + #print("The seepage is ", anb_seepage_flux) + def estimate_mt(self): + pass + def calculateSolutionAtQuadrature(self): + pass + def calculateAuxiliaryQuantitiesAfterStep(self): + pass + def postStep(self, t, firstStep=False): + with open('seepage_flux_nnnnk', "a") as f: + f.write("\n Time"+ ",\t" +"Seepage\n") + f.write(repr(t)+ ",\t" +repr(self.coefficients.anb_seepage_flux)) + + + +#argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux +#anb_seepage_flux= self.coefficients.anb_seepage_flux +#print("Hi",anb_seepage_flux) + + +#print("Hello from the python file", self.coefficients.anb_seepage_flux) diff --git a/richards_fct/richards/edit/Richards_edit.h b/richards_fct/richards/edit/Richards_edit.h new file mode 100755 index 0000000000..36a10ac428 --- /dev/null +++ b/richards_fct/richards/edit/Richards_edit.h @@ -0,0 +1,3205 @@ +#ifndef Richards_H +#define Richards_H +#include +#include +#include +#include "CompKernel.h" +#include "ModelFactory.h" +#include "../mprans/ArgumentsDict.h" +#include "xtensor-python/pyarray.hpp" +#define nnz nSpace + +namespace py = pybind11; +#define POWER_SMOOTHNESS_INDICATOR 2 +#define IS_BETAij_ONE 0 +#define GLOBAL_FCT 0 +namespace proteus +{ + // Power entropy // + inline double ENTROPY(const double& phi, const double& phiL, const double& phiR){ + return 1./2.*std::pow(fabs(phi),2.); + } + inline double DENTROPY(const double& phi, const double& phiL, const double& phiR){ + return fabs(phi)*(phi>=0 ? 1 : -1); + } + // Log entropy // for level set from 0 to 1 + inline double ENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ + return std::log(fabs((phi-phiL)*(phiR-phi))+1E-14); + } + inline double DENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ + return (phiL+phiR-2*phi)*((phi-phiL)*(phiR-phi)>=0 ? 1 : -1)/(fabs((phi-phiL)*(phiR-phi))+1E-14); + } +} + +namespace proteus + +{ + class Richards_base + { + //The base class defining the interface + public: + virtual ~Richards_base(){ + double anb_seepage_flux =1e-16; + } + virtual void calculateResidual(arguments_dict& args)=0; + virtual void calculateJacobian(arguments_dict& args)=0; + virtual void invert(arguments_dict& args)=0; + virtual void FCTStep(arguments_dict& args)=0; + virtual void kth_FCT_step(arguments_dict& args)=0; + virtual void calculateResidual_entropy_viscosity(arguments_dict& args)=0; + virtual void calculateMassMatrix(arguments_dict& args)=0; + }; + + template + class Richards : public Richards_base + { + public: + const int nDOF_test_X_trial_element; + CompKernelType ck; + Richards(): + nDOF_test_X_trial_element(nDOF_test_element*nDOF_trial_element), + ck() + {} + inline + void evaluateCoefficients(const int rowptr[nSpace], + const int colind[nnz], + const double rho, + const double beta, + const double gravity[nSpace], + const double alpha, + const double n_vg, + const double thetaR, + const double thetaSR, + const double KWs[nnz], + const double& u, + double& m, + double& dm, + double f[nSpace], + double df[nSpace], + double a[nnz], + double da[nnz], + double as[nnz], + double& kr, + double& dkr) + { + const int nSpace2 = nSpace * nSpace; + double psiC; + double pcBar; + double pcBar_n; + double pcBar_nM1; + double pcBar_nM2; + double onePlus_pcBar_n; + double sBar; + double sqrt_sBar; + double DsBar_DpsiC; + double thetaW; + double DthetaW_DpsiC; + double vBar; + double vBar2; + double DvBar_DpsiC; + double KWr; + double DKWr_DpsiC; + double rho2 = rho * rho; + double thetaS; + double rhom; + double drhom; + double m_vg; + double pcBarStar; + double sqrt_sBarStar; + + psiC = -u; + m_vg = 1.0 - 1.0 / n_vg; + thetaS = thetaR + thetaSR; + //std::cout<< "Thetas"< 0.0) + { + pcBar = alpha * psiC; + pcBarStar = pcBar; + if (pcBar < 1.0e-8) + pcBarStar = 1.0e-8; + pcBar_nM2 = pow(pcBarStar, n_vg - 2); + pcBar_nM1 = pcBar_nM2 * pcBar; + pcBar_n = pcBar_nM1 * pcBar; + onePlus_pcBar_n = 1.0 + pcBar_n; + + sBar = pow(onePlus_pcBar_n, -m_vg); + /* using -mn = 1-n */ + DsBar_DpsiC = alpha * (1.0 - n_vg) * (sBar/onePlus_pcBar_n)*pcBar_nM1; + + vBar = 1.0-pcBar_nM1*sBar; + vBar2 = vBar*vBar; + DvBar_DpsiC = -alpha*(n_vg-1.0)*pcBar_nM2*sBar - pcBar_nM1*DsBar_DpsiC; + + thetaW = thetaSR*sBar + thetaR; + DthetaW_DpsiC = thetaSR * DsBar_DpsiC; + + sqrt_sBar = sqrt(sBar); + sqrt_sBarStar = sqrt_sBar; + if (sqrt_sBar < 1.0e-8) + sqrt_sBarStar = 1.0e-8; + KWr= sqrt_sBar*vBar2; + DKWr_DpsiC= ((0.5/sqrt_sBarStar)*DsBar_DpsiC*vBar2 + + + 2.0*sqrt_sBar*vBar*DvBar_DpsiC); + } + else + { + thetaW = thetaS; + DthetaW_DpsiC = 0.0; + KWr = 1.0; + DKWr_DpsiC = 0.0; + } + //slight compressibility + rhom = rho*exp(beta*u); + drhom = beta*rhom; + m = rhom*thetaW; + dm = -rhom*DthetaW_DpsiC+drhom*thetaW; + for (int I=0;I thetaS || thetaW <= thetaR) + { + //cek debug + std::cout<<"rho "< 0.0) + { + isDOFBoundary = 1; + bc_u = bc_u_seepage; + } + else + { + isDOFBoundary = 0; + flux = 0.0; + } + } + /* //set DOF flag and flux correctly if seepage face */ + /* if (isSeepageFace) */ + /* { */ + /* if (flux < 0.0 || u < bc_u_seepage) */ + /* { */ + /* isDOFBoundary = 0; */ + /* flux = 0.0; */ + /* } */ + /* else */ + /* { */ + /* isDOFBoundary = 1; */ + /* bc_u = bc_u_seepage; */ + /* } */ + /* } */ + /* //Dirichlet penalty */ + /* if (isDOFBoundary) */ + /* flux += penalty*(u-bc_u); */ + } + else + flux = bc_flux; + } + + void exteriorNumericalFluxJacobian(const int rowptr[nSpace], + const int colind[nnz], + const int isDOFBoundary, + const double n[nSpace], + const double K[nnz], + const double dK[nnz], + const double grad_psi[nSpace], + const double grad_v[nSpace], + const double dK_rho_g[nSpace], + const double v, + const double penalty, + double& fluxJacobian) + { + if (isDOFBoundary) + { + fluxJacobian = 0.0; + for(int I=0;I& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + double sc_uref = args.scalar("sc_uref"); + double sc_alpha = args.scalar("sc_alpha"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& u_dof_old = args.array("u_dof_old"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m = args.array("q_m"); + xt::pyarray& q_u = args.array("q_u"); + xt::pyarray& q_dV = args.array("q_dV"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + int offset_u = args.scalar("offset_u"); + int stride_u = args.scalar("stride_u"); + xt::pyarray& globalResidual = args.array("globalResidual"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& ebqe_phi = args.array("ebqe_phi"); + double epsFact = args.scalar("epsFact"); + xt::pyarray& ebqe_u = args.array("ebqe_u"); + xt::pyarray& ebqe_flux = args.array("ebqe_flux"); + // PARAMETERS FOR EDGE BASED STABILIZATION + double cE = args.scalar("cE"); + double cK = args.scalar("cK"); + // PARAMETERS FOR LOG BASED ENTROPY FUNCTION + double uL = args.scalar("uL"); + double uR = args.scalar("uR"); + // PARAMETERS FOR EDGE VISCOSITY + int numDOFs = args.scalar("numDOFs"); + int NNZ = args.scalar("NNZ"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); + xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); + xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); + xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); + // C matrices + xt::pyarray& Cx = args.array("Cx"); + xt::pyarray& Cy = args.array("Cy"); + xt::pyarray& Cz = args.array("Cz"); + xt::pyarray& CTx = args.array("CTx"); + xt::pyarray& CTy = args.array("CTy"); + xt::pyarray& CTz = args.array("CTz"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); + int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); + // FOR FCT + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& fluxMatrix = args.array("fluxMatrix"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); + xt::pyarray& min_s_bc = args.array("min_s_bc"); + xt::pyarray& max_s_bc = args.array("max_s_bc"); + // AUX QUANTITIES OF INTEREST + xt::pyarray& quantDOFs = args.array("quantDOFs"); + xt::pyarray& sLow = args.array("sLow"); + xt::pyarray& sn = args.array("sn"); + + assert(a_rowptr.data()[nSpace] == nnz); + assert(a_rowptr.data()[nSpace] == nSpace); + //cek should this be read in? + double Ct_sge = 4.0; + //For flux Calculation + //double anb_seepage_flux=0.0; + //anb_seepage_flux = args["anb_seepage_flux"]; + //double anb_seepage_flux = args.scalar("anb_seepage_flux"); + //anb_seepage_flux=0.0; + + xt::pyarray& anb_seepage_flux_n = args.array("anb_seepage_flux_n"); + + + //double anb_seepage_flux=0.0; + double & anb_seepage_flux (args.scalar("anb_seepage_flux")) ; + //double anb_seepage_flux = args.scalar("anb_seepage_flux_n"); + + //double anb_seepage_flux=0.0; + anb_seepage_flux=0.0; + + //loop over elements to compute volume integrals and load them into element and global residual + // + //eN is the element index + //eN_k is the quadrature point index for a scalar + //eN_k_nSpace is the quadrature point index for a vector + //eN_i is the element test function index + //eN_j is the element trial function index + //eN_k_j is the quadrature point index for a trial function + //eN_k_i is the quadrature point index for a trial function + for(int eN=0;eN0) + { + std::cout<<"The seepage flux is "<& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); + xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); + xt::pyarray& globalJacobian = args.array("globalJacobian"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + assert(a_rowptr.data()[nSpace] == nnz); + assert(a_rowptr.data()[nSpace] == nSpace); + double Ct_sge = 4.0; + + + // + //loop over elements to compute volume integrals and load them into the element Jacobians and global Jacobian + // + for(int eN=0;eN& bc_mask = args.array("bc_mask"); + int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern + int numDOFs = args.scalar("numDOFs"); //number of DOFs + double dt = args.scalar("dt"); + xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) + xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn + xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn + xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& limited_solution = args.array("limited_solution"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets + xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices + xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 + xt::pyarray& max_s_bc = args.array("max_s_bc"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int MONOLITHIC = args.scalar("MONOLITHIC"); + register double Rpos[numDOFs], Rneg[numDOFs]; + register double FluxCorrectionMatrix[NNZ]; + register double solL[numDOFs]; + register double sdot[numDOFs]; + ////////////////// + // LOOP in DOFs // + ////////////////// + int ij=0; + for (int i=0; i 0) ? 1. : 0.); + Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); + + //update ij + ij+=1; + //std::cout<<"sdoti error"<0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])) + * FluxCorrectionMatrix[ij]; + alpha_dot = fmin(1.0, beta_ij*fabs(alpha_fA)/MassMatrix.data()[ij]/fmax(1.0e-8,fabs(sdoti-sdotj))); + if (MONOLITHIC == 0) + { + ith_Limiter_times_FluxCorrectionMatrix += alpha_fA; + } + else + { + ith_Limiter_times_FluxCorrectionMatrix += alpha_fA + (LUMPED_MASS_MATRIX == 1 ? 0. : 1.)*dt*alpha_dot*MassMatrix.data()[ij]*(sdoti-sdotj); + } + //update ij + ij+=1; + } + limited_solution.data()[i] = solL[i] + 1./lumped_mass_matrix.data()[i]*ith_Limiter_times_FluxCorrectionMatrix*bc_mask[i]; + } + } + + void kth_FCT_step(arguments_dict& args) + { + int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern + int numDOFs = args.scalar("numDOFs"); //number of DOFs + int num_fct_iter = args.scalar("num_fct_iter"); + double dt = args.scalar("dt"); + xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) + xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn + xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn + xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& solLim = args.array("limited_solution"); + xt::pyarray& MC = args.array("MC"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& FluxMatrix = args.array("FluxMatrix"); + xt::pyarray& limitedFlux = args.array("limited_Flux"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets + xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices + xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 + xt::pyarray& max_s_bc = args.array("max_s_bc"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int MONOLITHIC = args.scalar("MONOLITHIC"); + register double Rpos[numDOFs], Rneg[numDOFs]; + int ij=0; + + ////////////////////////////////////////////////////// + // ********** COMPUTE LOW ORDER SOLUTION ********** // + ////////////////////////////////////////////////////// + if (num_fct_iter == 0) + { // No FCT for global bounds + for (int i=0; i 0) ? 1. : 0.); + // update ij + ij+=1; + } + // compute Q vectors + double mi = ML.data()[i]; + double solLimi = solLim.data()[i]; + double Qposi = mi*(maxi-solLimi); + // compute R vectors + Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + } + ij=0; + for (int i=0; i0 ? Rposi : Rpos[j]); + // compute limited flux + ith_Limiter_times_FluxCorrectionMatrix += Lij*Fluxij; + + // update limited flux + limitedFlux.data()[ij] = Lij*Fluxij; + + //update FluxMatrix + FluxMatrix.data()[ij] = Fluxij; + + //update ij + ij+=1; + } + //update limited solution + double mi = ML.data()[i]; + solLim.data()[i] += 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; + } + } + } + + // ***************************************** // + // ********** HIGH ORDER SOLUTION ********** // + // ***************************************** // + ij=0; + for (int i=0; i 0 ? 1. : 0.); + Pnegi += fij * (fij < 0 ? 1. : 0.); + //update ij + ij+=1; + } + // compute Q vectors // + double mi = ML.data()[i]; + double Qposi = mi*(maxi-solLim.data()[i]); + double Qnegi = mi*(mini-solLim.data()[i]); + // compute R vectors // + Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); + } + + // COMPUTE LIMITERS // + ij=0; + for (int i=0; i 0 ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j]); + // compute ith_limited_flux_correction + ith_limited_flux_correction += Lij*fij; + ij+=1; + } + double mi = ML.data()[i]; + solLim[i] += 1./mi*ith_limited_flux_correction; + } + } + + void calculateResidual_entropy_viscosity(arguments_dict& args) + { + xt::pyarray& globalJacobian = args.array("globalJacobian"); + double Theta = args.scalar("Theta"); + xt::pyarray& bc_mask = args.array("bc_mask"); + double dt = args.scalar("dt"); + xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + double sc_uref = args.scalar("sc_uref"); + double sc_alpha = args.scalar("sc_alpha"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& r_l2g = args.array("r_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + int degree_polynomial = args.scalar("degree_polynomial"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& u_dof_old = args.array("u_dof_old"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m = args.array("q_m"); + xt::pyarray& q_u = args.array("q_u"); + xt::pyarray& q_dV = args.array("q_dV"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + int offset_u = args.scalar("offset_u"); + int stride_u = args.scalar("stride_u"); + xt::pyarray& globalResidual = args.array("globalResidual"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& ebqe_phi = args.array("ebqe_phi"); + double epsFact = args.scalar("epsFact"); + xt::pyarray& ebqe_u = args.array("ebqe_u"); + xt::pyarray& ebqe_flux = args.array("ebqe_flux"); + // PARAMETERS FOR EDGE BASED STABILIZATION + double cE = args.scalar("cE"); + double cK = args.scalar("cK"); + // PARAMETERS FOR LOG BASED ENTROPY FUNCTION + double uL = args.scalar("uL"); + double uR = args.scalar("uR"); + // PARAMETERS FOR EDGE VISCOSITY + int numDOFs = args.scalar("numDOFs"); + int NNZ = args.scalar("NNZ"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); + xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); + xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); + xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); + // C matrices + xt::pyarray& Cx = args.array("Cx"); + xt::pyarray& Cy = args.array("Cy"); + xt::pyarray& Cz = args.array("Cz"); + xt::pyarray& CTx = args.array("CTx"); + xt::pyarray& CTy = args.array("CTy"); + xt::pyarray& CTz = args.array("CTz"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); + int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); + // FOR FCT + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& fluxMatrix = args.array("fluxMatrix"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); + xt::pyarray& min_s_bc = args.array("min_s_bc"); + xt::pyarray& max_s_bc = args.array("max_s_bc"); + // AUX QUANTITIES OF INTEREST + xt::pyarray& quantDOFs = args.array("quantDOFs"); + xt::pyarray& sLow = args.array("sLow"); + xt::pyarray& sn = args.array("sn"); + + xt::pyarray& anb_seepage_flux_n = args.array("anb_seepage_flux_n"); + + + //double anb_seepage_flux=0.0; + double & anb_seepage_flux (args.scalar("anb_seepage_flux")) ; + //double anb_seepage_flux = args.scalar("anb_seepage_flux_n"); + + //double anb_seepage_flux=0.0; + anb_seepage_flux=0.0; + + + register double Rpos[numDOFs], Rneg[numDOFs]; + //register double FluxCorrectionMatrix[NNZ]; + // NOTE: This function follows a different (but equivalent) implementation of the smoothness based indicator than NCLS.h + // Allocate space for the transport matrices + // This is used for first order KUZMIN'S METHOD + register double TransportMatrix[NNZ],TransportMatrixConsistent[NNZ]; + register double TransportMatrixn[NNZ],TransportMatrixConsistentn[NNZ]; + std::valarray u_free_dof(numDOFs); + std::valarray u_free_dof_old(numDOFs); + std::valarray ML2(numDOFs); + + + for(int eN=0;eN0) + { + std::cout<<"The seepage flux is "<("anb_seepage_flux_n"); + //anb_seepage_flux_n=0.0; + + //anb_seepage_flux_n= anb_seepage_flux; + + + + //if (isSeepageFace) + //{ + // anb_seepage_flux+= dS* flux_ext; + // std::cout<<"The seepage flux is "<0){ + // std::cout<<"The seepage flux is "<= 0 && isFluxBoundary_u[ebNE_kb] != 1 ) //outflow. This is handled via the transport matrices. Then flux_ext=0 and dflux_ext!=0 + // { + // dflux_ext = flow; + // flux_ext = 0; + // // save external u + // ebqe_u[ebNE_kb] = u_ext; + // } + //else // inflow. This is handled via the boundary integral. Then flux_ext!=0 and dflux_ext=0 + //{ + //dflux_ext = 0; + // save external u + //ebqe_u[ebNE_kb] = isDOFBoundary_u[ebNE_kb]*ebqe_bc_u_ext[ebNE_kb]+(1-isDOFBoundary_u[ebNE_kb])*u_ext; + //if (isDOFBoundary_u[ebNE_kb] == 1) + // flux_ext = ebqe_bc_u_ext[ebNE_kb]*flow; + //else if (isFluxBoundary_u[ebNE_kb] == 1) + //flux_ext = ebqe_bc_flux_u_ext[ebNE_kb]; + // flux_ext = ebqe_bc_u_ext[ebNE_kb]; + //else + // { + // std::cout<<"warning: VOF open boundary with no external trace, setting to zero for inflow"<= 0.) + { + alpha_numerator_pos += alpha_num; + alpha_denominator_pos += alpha_num; + } + else + { + alpha_numerator_neg += alpha_num; + alpha_denominator_neg += fabs(alpha_num); + } + //update ij + ij+=1; + } + // scale g vector by lumped mass matrix + if (fabs(ML.data()[i] - ML2[i]) > 1.0e-16) + std::cout<<"ML "< 0.0) + // assert( (xi[I] - xj[I]) == delta_x_ij[offset*3+I]); + //gi_times_x += gi[I]*(xi[I]-xj[I]); + gi_times_x += gi[I]*delta_x_ij.data()[offset*3+I]; + } + // compute the positive and negative part of gi*(xi-xj) + SumPos += gi_times_x > 0 ? gi_times_x : 0; + SumNeg += gi_times_x < 0 ? gi_times_x : 0; + } + double sigmaPosi = fmin(1.,(fabs(SumNeg)+1E-15)/(SumPos+1E-15)); + double sigmaNegi = fmin(1.,(SumPos+1E-15)/(fabs(SumNeg)+1E-15)); + double alpha_numi = fabs(sigmaPosi*alpha_numerator_pos + sigmaNegi*alpha_numerator_neg); + double alpha_deni = sigmaPosi*alpha_denominator_pos + sigmaNegi*alpha_denominator_neg; + if (IS_BETAij_ONE == 1) + { + alpha_numi = fabs(alpha_numerator_pos + alpha_numerator_neg); + alpha_deni = alpha_denominator_pos + alpha_denominator_neg; + } + double alphai = alpha_numi/(alpha_deni+1E-15); + quantDOFs.data()[i] = alphai; + + if (POWER_SMOOTHNESS_INDICATOR==0) + psi[i] = 1.0; + else + psi[i] = std::pow(alphai,POWER_SMOOTHNESS_INDICATOR); //NOTE: they use alpha^2 in the paper + } + ///////////////////////////////////////////// + // ** LOOP IN DOFs FOR EDGE BASED TERMS ** // + ///////////////////////////////////////////// + ij=0; + for (int i=0; i Dissipation matrices as well. + double soli = u_free_dof[i]; // solution at time tn for the ith DOF + double solni = u_free_dof_old[i]; // solution at time tn for the ith DOF + for (int I=0;I mMax) + { + std::cout<<"mass out of bounds "< 0) ? 1. : 0.); + // Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); + // ij+=1; + // } + // double mi = ML[i]; + // double solni = u_dof_old[i]; + // double Qposi = mi*(maxi-solni); + // double Qnegi = mi*(mini-solni); + + //std::cout << Qposi << std::endl; + // Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + // Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); + + //if (Rpos[i] < 0) + //{ + // std::cout << mi << "\t" << maxi << "\t" << solni << std::endl; + // std::cout << Qposi << "\t" << Pposi << std::endl; + // std::cout << Rpos[i] << std::endl; + //abort(); + //} + //} + + //ij=0; + //for (int i=0; i 1.0 || Rposi < 0.0) + //std::cout << "Rposi: " << Rposi << std::endl; + //if (Rnegi > 1.0 || Rnegi < 0.0) + //std::cout << "Rnegi: " << Rnegi << std::endl; + + // LOOP OVER THE SPARSITY PATTERN (j-LOOP)// + // for (int offset=csrRowIndeces_DofLoops.data()[i]; + // offset0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])); + // //Lij=0.0; + // ith_Limiter_times_FluxCorrectionMatrix += Lij*FluxCorrectionMatrix[ij]; + // //update ij + // ij+=1; + // } + // double mi = ML[i]; + // double solni = u_dof_old[i]; + // globalResidual[i] = solni + 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; + //} + } + + + void invert(arguments_dict& args) + { + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + xt::pyarray& globalResidual = args.array("globalResidual"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + int numDOFs = args.scalar("numDOFs"); + for (int i=0; i mMax) + { + std::cout<<"mass out of bounds "<("dt"); + xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + //element boundary + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + //physics + int nElements_global = args.scalar("nElements_global"); + //new + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + //end new + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& r_l2g = args.array("r_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + int degree_polynomial = args.scalar("degree_polynomial"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); + xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); + xt::pyarray& globalJacobian = args.array("globalJacobian"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + //std::cout<<"ndjaco address "<(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + else if (nSpaceIn == 2) + return proteus::chooseAndAllocateDiscretization2D(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + else + { + assert(nSpaceIn == 3); + return proteus::chooseAndAllocateDiscretization(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + } + } +};//proteus +#endif \ No newline at end of file diff --git a/richards_fct/richards/edit/Richards_edit_n.h b/richards_fct/richards/edit/Richards_edit_n.h new file mode 100644 index 0000000000..789cf629e3 --- /dev/null +++ b/richards_fct/richards/edit/Richards_edit_n.h @@ -0,0 +1,3342 @@ +#ifndef Richards_H +#define Richards_H +#include +#include +#include +#include "CompKernel.h" +#include "ModelFactory.h" +#include "../mprans/ArgumentsDict.h" +#include "xtensor-python/pyarray.hpp" +#define nnz nSpace + +namespace py = pybind11; +#define POWER_SMOOTHNESS_INDICATOR 2 +#define IS_BETAij_ONE 0 +#define GLOBAL_FCT 0 +namespace proteus +{ + // Power entropy // + inline double ENTROPY(const double& phi, const double& phiL, const double& phiR){ + return 1./2.*std::pow(fabs(phi),2.); + } + inline double DENTROPY(const double& phi, const double& phiL, const double& phiR){ + return fabs(phi)*(phi>=0 ? 1 : -1); + } + // Log entropy // for level set from 0 to 1 + inline double ENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ + return std::log(fabs((phi-phiL)*(phiR-phi))+1E-14); + } + inline double DENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ + return (phiL+phiR-2*phi)*((phi-phiL)*(phiR-phi)>=0 ? 1 : -1)/(fabs((phi-phiL)*(phiR-phi))+1E-14); + } +} + +namespace proteus + +{ + class Richards_base + { + //The base class defining the interface + public: + virtual ~Richards_base(){ + double anb_seepage_flux =1e-16; + } + virtual void calculateResidual(arguments_dict& args)=0; + virtual void calculateJacobian(arguments_dict& args)=0; + virtual void invert(arguments_dict& args)=0; + virtual void FCTStep(arguments_dict& args)=0; + virtual void kth_FCT_step(arguments_dict& args)=0; + virtual void calculateResidual_entropy_viscosity(arguments_dict& args)=0; + virtual void calculateMassMatrix(arguments_dict& args)=0; + }; + + template + class Richards : public Richards_base + { + public: + const int nDOF_test_X_trial_element; + CompKernelType ck; + Richards(): + nDOF_test_X_trial_element(nDOF_test_element*nDOF_trial_element), + ck() + {} + inline + void evaluateCoefficients(const int rowptr[nSpace], + const int colind[nnz], + const double rho, + const double beta, + const double gravity[nSpace], + const double alpha, + const double n_vg, + const double thetaR, + const double thetaSR, + const double KWs[nnz], + const double& u, + double& m, + double& dm, + double f[nSpace], + double df[nSpace], + double a[nnz], + double da[nnz], + double as[nnz], + double& kr, + double& dkr) + { + const int nSpace2 = nSpace * nSpace; + double psiC; + double pcBar; + double pcBar_n; + double pcBar_nM1; + double pcBar_nM2; + double onePlus_pcBar_n; + double sBar; + double sqrt_sBar; + double DsBar_DpsiC; + double thetaW; + double DthetaW_DpsiC; + double vBar; + double vBar2; + double DvBar_DpsiC; + double KWr; + double DKWr_DpsiC; + double rho2 = rho * rho; + double thetaS; + double rhom; + double drhom; + double m_vg; + double pcBarStar; + double sqrt_sBarStar; + + psiC = -u; + m_vg = 1.0 - 1.0 / n_vg; + thetaS = thetaR + thetaSR; + //std::cout<< "Thetas"< 0.0) + { + pcBar = alpha * psiC; + pcBarStar = pcBar; + if (pcBar < 1.0e-8) + pcBarStar = 1.0e-8; + pcBar_nM2 = pow(pcBarStar, n_vg - 2); + pcBar_nM1 = pcBar_nM2 * pcBar; + pcBar_n = pcBar_nM1 * pcBar; + onePlus_pcBar_n = 1.0 + pcBar_n; + + sBar = pow(onePlus_pcBar_n, -m_vg); + /* using -mn = 1-n */ + DsBar_DpsiC = alpha * (1.0 - n_vg) * (sBar/onePlus_pcBar_n)*pcBar_nM1; + + vBar = 1.0-pcBar_nM1*sBar; + vBar2 = vBar*vBar; + DvBar_DpsiC = -alpha*(n_vg-1.0)*pcBar_nM2*sBar - pcBar_nM1*DsBar_DpsiC; + + thetaW = thetaSR*sBar + thetaR; + DthetaW_DpsiC = thetaSR * DsBar_DpsiC; + + sqrt_sBar = sqrt(sBar); + sqrt_sBarStar = sqrt_sBar; + if (sqrt_sBar < 1.0e-8) + sqrt_sBarStar = 1.0e-8; + KWr= sqrt_sBar*vBar2; + DKWr_DpsiC= ((0.5/sqrt_sBarStar)*DsBar_DpsiC*vBar2 + + + 2.0*sqrt_sBar*vBar*DvBar_DpsiC); + } + else + { + thetaW = thetaS; + DthetaW_DpsiC = 0.0; + KWr = 1.0; + DKWr_DpsiC = 0.0; + } + //slight compressibility + rhom = rho*exp(beta*u); + drhom = beta*rhom; + m = rhom*thetaW; + dm = -rhom*DthetaW_DpsiC+drhom*thetaW; + for (int I=0;I thetaS || thetaW <= thetaR) + { + //cek debug + std::cout<<"rho "< 0.0) + { + isDOFBoundary = 1; + bc_u = bc_u_seepage; + } + else + { + isDOFBoundary = 0; + flux = 0.0; + } + } + /* //set DOF flag and flux correctly if seepage face */ + /* if (isSeepageFace) */ + /* { */ + /* if (flux < 0.0 || u < bc_u_seepage) */ + /* { */ + /* isDOFBoundary = 0; */ + /* flux = 0.0; */ + /* } */ + /* else */ + /* { */ + /* isDOFBoundary = 1; */ + /* bc_u = bc_u_seepage; */ + /* } */ + /* } */ + /* //Dirichlet penalty */ + /* if (isDOFBoundary) */ + /* flux += penalty*(u-bc_u); */ + } + else + flux = bc_flux; + } + + void exteriorNumericalFluxJacobian(const int rowptr[nSpace], + const int colind[nnz], + const int isDOFBoundary, + const double n[nSpace], + const double K[nnz], + const double dK[nnz], + const double grad_psi[nSpace], + const double grad_v[nSpace], + const double dK_rho_g[nSpace], + const double v, + const double penalty, + double& fluxJacobian) + { + if (isDOFBoundary) + { + fluxJacobian = 0.0; + for(int I=0;I& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + double sc_uref = args.scalar("sc_uref"); + double sc_alpha = args.scalar("sc_alpha"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& u_dof_old = args.array("u_dof_old"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m = args.array("q_m"); + xt::pyarray& q_u = args.array("q_u"); + xt::pyarray& q_dV = args.array("q_dV"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + int offset_u = args.scalar("offset_u"); + int stride_u = args.scalar("stride_u"); + xt::pyarray& globalResidual = args.array("globalResidual"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& ebqe_phi = args.array("ebqe_phi"); + double epsFact = args.scalar("epsFact"); + xt::pyarray& ebqe_u = args.array("ebqe_u"); + xt::pyarray& ebqe_flux = args.array("ebqe_flux"); + // PARAMETERS FOR EDGE BASED STABILIZATION + double cE = args.scalar("cE"); + double cK = args.scalar("cK"); + // PARAMETERS FOR LOG BASED ENTROPY FUNCTION + double uL = args.scalar("uL"); + double uR = args.scalar("uR"); + // PARAMETERS FOR EDGE VISCOSITY + int numDOFs = args.scalar("numDOFs"); + int NNZ = args.scalar("NNZ"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); + xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); + xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); + xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); + // C matrices + xt::pyarray& Cx = args.array("Cx"); + xt::pyarray& Cy = args.array("Cy"); + xt::pyarray& Cz = args.array("Cz"); + xt::pyarray& CTx = args.array("CTx"); + xt::pyarray& CTy = args.array("CTy"); + xt::pyarray& CTz = args.array("CTz"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); + int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); + // FOR FCT + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& fluxMatrix = args.array("fluxMatrix"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); + xt::pyarray& min_s_bc = args.array("min_s_bc"); + xt::pyarray& max_s_bc = args.array("max_s_bc"); + // AUX QUANTITIES OF INTEREST + xt::pyarray& quantDOFs = args.array("quantDOFs"); + xt::pyarray& sLow = args.array("sLow"); + xt::pyarray& sn = args.array("sn"); + + assert(a_rowptr.data()[nSpace] == nnz); + assert(a_rowptr.data()[nSpace] == nSpace); + //cek should this be read in? + double Ct_sge = 4.0; + //For flux Calculation + //double anb_seepage_flux=0.0; + //anb_seepage_flux = args["anb_seepage_flux"]; + //double anb_seepage_flux = args.scalar("anb_seepage_flux"); + //anb_seepage_flux=0.0; + + xt::pyarray& anb_seepage_flux_n = args.array("anb_seepage_flux_n"); + + + //double anb_seepage_flux=0.0; + double & anb_seepage_flux (args.scalar("anb_seepage_flux")) ; + //double anb_seepage_flux = args.scalar("anb_seepage_flux_n"); + + //double anb_seepage_flux=0.0; + anb_seepage_flux=0.0; + + //loop over elements to compute volume integrals and load them into element and global residual + // + //eN is the element index + //eN_k is the quadrature point index for a scalar + //eN_k_nSpace is the quadrature point index for a vector + //eN_i is the element test function index + //eN_j is the element trial function index + //eN_k_j is the quadrature point index for a trial function + //eN_k_i is the quadrature point index for a trial function + for(int eN=0;eN0) + { + std::cout<<"The seepage flux is "<& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); + xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); + xt::pyarray& globalJacobian = args.array("globalJacobian"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + assert(a_rowptr.data()[nSpace] == nnz); + assert(a_rowptr.data()[nSpace] == nSpace); + double Ct_sge = 4.0; + + + // + //loop over elements to compute volume integrals and load them into the element Jacobians and global Jacobian + // + for(int eN=0;eN& bc_mask = args.array("bc_mask"); + int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern + int numDOFs = args.scalar("numDOFs"); //number of DOFs + double dt = args.scalar("dt"); + xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) + xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn + xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn + xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& limited_solution = args.array("limited_solution"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets + xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices + xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 + xt::pyarray& max_s_bc = args.array("max_s_bc"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int MONOLITHIC = args.scalar("MONOLITHIC"); + register double Rpos[numDOFs], Rneg[numDOFs]; + register double FluxCorrectionMatrix[NNZ]; + register double solL[numDOFs]; + register double sdot[numDOFs]; + ////////////////// + // LOOP in DOFs // + ////////////////// + int ij=0; + for (int i=0; i 0) ? 1. : 0.); + Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); + + //update ij + ij+=1; + //std::cout<<"sdoti error"<0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])) + * FluxCorrectionMatrix[ij]; + alpha_dot = fmin(1.0, beta_ij*fabs(alpha_fA)/MassMatrix.data()[ij]/fmax(1.0e-8,fabs(sdoti-sdotj))); + if (MONOLITHIC == 0) + { + ith_Limiter_times_FluxCorrectionMatrix += alpha_fA; + } + else + { + ith_Limiter_times_FluxCorrectionMatrix += alpha_fA + (LUMPED_MASS_MATRIX == 1 ? 0. : 1.)*dt*alpha_dot*MassMatrix.data()[ij]*(sdoti-sdotj); + } + //update ij + ij+=1; + } + limited_solution.data()[i] = solL[i] + 1./lumped_mass_matrix.data()[i]*ith_Limiter_times_FluxCorrectionMatrix*bc_mask[i]; + } + } + + void kth_FCT_step(arguments_dict& args) + { + int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern + int numDOFs = args.scalar("numDOFs"); //number of DOFs + int num_fct_iter = args.scalar("num_fct_iter"); + double dt = args.scalar("dt"); + xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) + xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn + xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn + xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& solLim = args.array("limited_solution"); + xt::pyarray& MC = args.array("MC"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& FluxMatrix = args.array("FluxMatrix"); + xt::pyarray& limitedFlux = args.array("limited_Flux"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets + xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices + xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 + xt::pyarray& max_s_bc = args.array("max_s_bc"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int MONOLITHIC = args.scalar("MONOLITHIC"); + register double Rpos[numDOFs], Rneg[numDOFs]; + int ij=0; + + ////////////////////////////////////////////////////// + // ********** COMPUTE LOW ORDER SOLUTION ********** // + ////////////////////////////////////////////////////// + if (num_fct_iter == 0) + { // No FCT for global bounds + for (int i=0; i 0) ? 1. : 0.); + // update ij + ij+=1; + } + // compute Q vectors + double mi = ML.data()[i]; + double solLimi = solLim.data()[i]; + double Qposi = mi*(maxi-solLimi); + // compute R vectors + Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + } + ij=0; + for (int i=0; i0 ? Rposi : Rpos[j]); + // compute limited flux + ith_Limiter_times_FluxCorrectionMatrix += Lij*Fluxij; + + // update limited flux + limitedFlux.data()[ij] = Lij*Fluxij; + + //update FluxMatrix + FluxMatrix.data()[ij] = Fluxij; + + //update ij + ij+=1; + } + //update limited solution + double mi = ML.data()[i]; + solLim.data()[i] += 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; + } + } + } + + // ***************************************** // + // ********** HIGH ORDER SOLUTION ********** // + // ***************************************** // + ij=0; + for (int i=0; i 0 ? 1. : 0.); + Pnegi += fij * (fij < 0 ? 1. : 0.); + //update ij + ij+=1; + } + // compute Q vectors // + double mi = ML.data()[i]; + double Qposi = mi*(maxi-solLim.data()[i]); + double Qnegi = mi*(mini-solLim.data()[i]); + // compute R vectors // + Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); + } + + // COMPUTE LIMITERS // + ij=0; + for (int i=0; i 0 ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j]); + // compute ith_limited_flux_correction + ith_limited_flux_correction += Lij*fij; + ij+=1; + } + double mi = ML.data()[i]; + solLim[i] += 1./mi*ith_limited_flux_correction; + } + } + + void calculateResidual_entropy_viscosity(arguments_dict& args) + { + xt::pyarray& globalJacobian = args.array("globalJacobian"); + double Theta = args.scalar("Theta"); + xt::pyarray& bc_mask = args.array("bc_mask"); + double dt = args.scalar("dt"); + xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + double sc_uref = args.scalar("sc_uref"); + double sc_alpha = args.scalar("sc_alpha"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& r_l2g = args.array("r_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + int degree_polynomial = args.scalar("degree_polynomial"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& u_dof_old = args.array("u_dof_old"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m = args.array("q_m"); + xt::pyarray& q_u = args.array("q_u"); + xt::pyarray& q_dV = args.array("q_dV"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + int offset_u = args.scalar("offset_u"); + int stride_u = args.scalar("stride_u"); + xt::pyarray& globalResidual = args.array("globalResidual"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& ebqe_phi = args.array("ebqe_phi"); + double epsFact = args.scalar("epsFact"); + xt::pyarray& ebqe_u = args.array("ebqe_u"); + xt::pyarray& ebqe_flux = args.array("ebqe_flux"); + // PARAMETERS FOR EDGE BASED STABILIZATION + double cE = args.scalar("cE"); + double cK = args.scalar("cK"); + // PARAMETERS FOR LOG BASED ENTROPY FUNCTION + double uL = args.scalar("uL"); + double uR = args.scalar("uR"); + // PARAMETERS FOR EDGE VISCOSITY + int numDOFs = args.scalar("numDOFs"); + int NNZ = args.scalar("NNZ"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); + xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); + xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); + xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); + // C matrices + xt::pyarray& Cx = args.array("Cx"); + xt::pyarray& Cy = args.array("Cy"); + xt::pyarray& Cz = args.array("Cz"); + xt::pyarray& CTx = args.array("CTx"); + xt::pyarray& CTy = args.array("CTy"); + xt::pyarray& CTz = args.array("CTz"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); + int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); + // FOR FCT + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& fluxMatrix = args.array("fluxMatrix"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); + xt::pyarray& min_s_bc = args.array("min_s_bc"); + xt::pyarray& max_s_bc = args.array("max_s_bc"); + // AUX QUANTITIES OF INTEREST + xt::pyarray& quantDOFs = args.array("quantDOFs"); + xt::pyarray& sLow = args.array("sLow"); + xt::pyarray& sn = args.array("sn"); + + xt::pyarray& anb_seepage_flux_n = args.array("anb_seepage_flux_n"); + + + //double anb_seepage_flux=0.0; + double & anb_seepage_flux (args.scalar("anb_seepage_flux")) ; + //double anb_seepage_flux = args.scalar("anb_seepage_flux_n"); + + //double anb_seepage_flux=0.0; + anb_seepage_flux=0.0; + + + register double Rpos[numDOFs], Rneg[numDOFs]; + //register double FluxCorrectionMatrix[NNZ]; + // NOTE: This function follows a different (but equivalent) implementation of the smoothness based indicator than NCLS.h + // Allocate space for the transport matrices + // This is used for first order KUZMIN'S METHOD + register double TransportMatrix[NNZ],TransportMatrixConsistent[NNZ]; + register double TransportMatrixn[NNZ],TransportMatrixConsistentn[NNZ]; + std::valarray u_free_dof(numDOFs); + std::valarray u_free_dof_old(numDOFs); + std::valarray ML2(numDOFs); + + + for(int eN=0;eN0) + { + std::cout<<"The seepage flux is "<("anb_seepage_flux_n"); + //anb_seepage_flux_n=0.0; + + //anb_seepage_flux_n= anb_seepage_flux; + + + + //if (isSeepageFace) + //{ + // anb_seepage_flux+= dS* flux_ext; + // std::cout<<"The seepage flux is "<0){ + // std::cout<<"The seepage flux is "<= 0 && isFluxBoundary_u[ebNE_kb] != 1 ) //outflow. This is handled via the transport matrices. Then flux_ext=0 and dflux_ext!=0 + // { + // dflux_ext = flow; + // flux_ext = 0; + // // save external u + // ebqe_u[ebNE_kb] = u_ext; + // } + //else // inflow. This is handled via the boundary integral. Then flux_ext!=0 and dflux_ext=0 + //{ + //dflux_ext = 0; + // save external u + //ebqe_u[ebNE_kb] = isDOFBoundary_u[ebNE_kb]*ebqe_bc_u_ext[ebNE_kb]+(1-isDOFBoundary_u[ebNE_kb])*u_ext; + //if (isDOFBoundary_u[ebNE_kb] == 1) + // flux_ext = ebqe_bc_u_ext[ebNE_kb]*flow; + //else if (isFluxBoundary_u[ebNE_kb] == 1) + //flux_ext = ebqe_bc_flux_u_ext[ebNE_kb]; + // flux_ext = ebqe_bc_u_ext[ebNE_kb]; + //else + // { + // std::cout<<"warning: VOF open boundary with no external trace, setting to zero for inflow"<= 0.) + { + alpha_numerator_pos += alpha_num; + alpha_denominator_pos += alpha_num; + } + else + { + alpha_numerator_neg += alpha_num; + alpha_denominator_neg += fabs(alpha_num); + } + //update ij + ij+=1; + } + // scale g vector by lumped mass matrix + if (fabs(ML.data()[i] - ML2[i]) > 1.0e-16) + std::cout<<"ML "< 0.0) + // assert( (xi[I] - xj[I]) == delta_x_ij[offset*3+I]); + //gi_times_x += gi[I]*(xi[I]-xj[I]); + gi_times_x += gi[I]*delta_x_ij.data()[offset*3+I]; + } + // compute the positive and negative part of gi*(xi-xj) + SumPos += gi_times_x > 0 ? gi_times_x : 0; + SumNeg += gi_times_x < 0 ? gi_times_x : 0; + } + double sigmaPosi = fmin(1.,(fabs(SumNeg)+1E-15)/(SumPos+1E-15)); + double sigmaNegi = fmin(1.,(SumPos+1E-15)/(fabs(SumNeg)+1E-15)); + double alpha_numi = fabs(sigmaPosi*alpha_numerator_pos + sigmaNegi*alpha_numerator_neg); + double alpha_deni = sigmaPosi*alpha_denominator_pos + sigmaNegi*alpha_denominator_neg; + if (IS_BETAij_ONE == 1) + { + alpha_numi = fabs(alpha_numerator_pos + alpha_numerator_neg); + alpha_deni = alpha_denominator_pos + alpha_denominator_neg; + } + double alphai = alpha_numi/(alpha_deni+1E-15); + quantDOFs.data()[i] = alphai; + + if (POWER_SMOOTHNESS_INDICATOR==0) + psi[i] = 1.0; + else + psi[i] = std::pow(alphai,POWER_SMOOTHNESS_INDICATOR); //NOTE: they use alpha^2 in the paper + } + ///////////////////////////////////////////// + // ** LOOP IN DOFs FOR EDGE BASED TERMS ** // + ///////////////////////////////////////////// + ij=0; + for (int i=0; i Dissipation matrices as well. + double soli = u_free_dof[i]; // solution at time tn for the ith DOF + double solni = u_free_dof_old[i]; // solution at time tn for the ith DOF + for (int I=0;I& bc_mask = args.array("bc_mask"); + //int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern + //int numDOFs = args.scalar("numDOFs"); //number of DOFs + //double dt = args.scalar("dt"); + //xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) + + //xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn + xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn + xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 + //xt::pyarray& uLow = args.array("uLow"); + //xt::pyarray& uDotLow = args.array("uDotLow"); + //xt::pyarray& limited_solution = args.array("limited_solution"); + //xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces + //xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets + xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix + //xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices + //xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 + //xt::pyarray& max_s_bc = args.array("max_s_bc"); + //int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + //int MONOLITHIC = args.scalar("MONOLITHIC"); + register double Rpos[numDOFs], Rneg[numDOFs]; + register double FluxCorrectionMatrix[NNZ]; + register double solL[numDOFs]; + register double sdot[numDOFs]; + + int ij=0; + for (int i=0; i 0) ? 1. : 0.); + Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); + + //update ij + ij+=1; + //std::cout<<"sdoti error"<0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])) + * FluxCorrectionMatrix[ij]; + alpha_dot = fmin(1.0, beta_ij*fabs(alpha_fA)/MassMatrix.data()[ij]/fmax(1.0e-8,fabs(sdoti-sdotj))); + + ith_Limiter_times_FluxCorrectionMatrix += alpha_fA; + //update ij + ij+=1; + } + + + //std::cout<<"Limiter "<< ith_Limiter_times_FluxCorrectionMatrix < mMax) + { + std::cout<<"mass out of bounds "< 0) ? 1. : 0.); + // Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); + // ij+=1; + // } + // double mi = ML[i]; + // double solni = u_dof_old[i]; + // double Qposi = mi*(maxi-solni); + // double Qnegi = mi*(mini-solni); + + //std::cout << Qposi << std::endl; + // Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + // Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); + + //if (Rpos[i] < 0) + //{ + // std::cout << mi << "\t" << maxi << "\t" << solni << std::endl; + // std::cout << Qposi << "\t" << Pposi << std::endl; + // std::cout << Rpos[i] << std::endl; + //abort(); + //} + } + + //ij=0; + //for (int i=0; i 1.0 || Rposi < 0.0) + //std::cout << "Rposi: " << Rposi << std::endl; + //if (Rnegi > 1.0 || Rnegi < 0.0) + //std::cout << "Rnegi: " << Rnegi << std::endl; + + // LOOP OVER THE SPARSITY PATTERN (j-LOOP)// + // for (int offset=csrRowIndeces_DofLoops.data()[i]; + // offset0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])); + // //Lij=0.0; + // ith_Limiter_times_FluxCorrectionMatrix += Lij*FluxCorrectionMatrix[ij]; + // //update ij + // ij+=1; + // } + // double mi = ML[i]; + // double solni = u_dof_old[i]; + // globalResidual[i] = solni + 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; + //} + } + + + void invert(arguments_dict& args) + { + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + xt::pyarray& globalResidual = args.array("globalResidual"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + int numDOFs = args.scalar("numDOFs"); + for (int i=0; i mMax) + { + std::cout<<"mass out of bounds "<("dt"); + xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + //element boundary + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + //physics + int nElements_global = args.scalar("nElements_global"); + //new + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + //end new + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& r_l2g = args.array("r_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + int degree_polynomial = args.scalar("degree_polynomial"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); + xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); + xt::pyarray& globalJacobian = args.array("globalJacobian"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + //std::cout<<"ndjaco address "<(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + else if (nSpaceIn == 2) + return proteus::chooseAndAllocateDiscretization2D(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + else + { + assert(nSpaceIn == 3); + return proteus::chooseAndAllocateDiscretization(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + } + } +};//proteus +#endif \ No newline at end of file diff --git a/richards_fct/richards/edit/Richards_edit_n.py b/richards_fct/richards/edit/Richards_edit_n.py new file mode 100644 index 0000000000..b299d490ce --- /dev/null +++ b/richards_fct/richards/edit/Richards_edit_n.py @@ -0,0 +1,1873 @@ +from __future__ import division +from builtins import range +from past.utils import old_div +import proteus +from .cRichards import * +import numpy as np +from proteus.Transport import OneLevelTransport +from proteus.Transport import TC_base, NonlinearEquation, logEvent, memory +from proteus.Transport import FluxBoundaryConditions, Comm, cfemIntegrals +from proteus.Transport import DOFBoundaryConditions, Quadrature +from proteus.mprans import cArgumentsDict +from proteus.LinearAlgebraTools import SparseMat +from proteus import TimeIntegration +from proteus.NonlinearSolvers import ExplicitLumpedMassMatrixForRichards +from proteus.NonlinearSolvers import Newton + + +class ThetaScheme(TimeIntegration.BackwardEuler): + def __init__(self,transport,integrateInterpolationPoints=False): + self.transport=transport + TimeIntegration.BackwardEuler.__init__(self,transport, integrateInterpolationPoints) + def updateTimeHistory(self,resetFromDOF=False): + TimeIntegration.BackwardEuler.updateTimeHistory(self,resetFromDOF) + self.transport.u_dof_old[:] = self.u +class RKEV(TimeIntegration.SSP): + from proteus import TimeIntegration + """ + Wrapper for SSPRK time integration using EV + + ... more to come ... + """ + + def __init__(self, transport, timeOrder=1, runCFL=0.1, integrateInterpolationPoints=False): + TimeIntegration.SSP.__init__(self, transport, integrateInterpolationPoints=integrateInterpolationPoints) + self.runCFL = runCFL + self.dtLast = None + self.isAdaptive = True + # About the cfl + assert transport.coefficients.STABILIZATION_TYPE > 0, "SSP method just works for edge based EV methods; i.e., STABILIZATION_TYPE>0" + assert hasattr(transport, 'edge_based_cfl'), "No edge based cfl defined" + self.cfl = transport.edge_based_cfl + # Stuff particular for SSP + self.timeOrder = timeOrder # order of approximation + self.nStages = timeOrder # number of stages total + self.lstage = 0 # last stage completed + # storage vectors + self.u_dof_last = {} + # per component stage values, list with array at each stage + self.u_dof_stage = {} + for ci in range(self.nc): + if ('m', ci) in transport.q: + self.u_dof_last[ci] = transport.u[ci].dof.copy() + self.u_dof_stage[ci] = [] + for k in range(self.nStages + 1): + self.u_dof_stage[ci].append(transport.u[ci].dof.copy()) + #print() + + + # def set_dt(self, DTSET): + # self.dt = DTSET # don't update t + def choose_dt(self): + comm = Comm.get() + maxCFL = 1.0e-6 + maxCFL = max(maxCFL, comm.globalMax(self.cfl.max())) + self.dt = old_div(self.runCFL, maxCFL) + if self.dtLast is None: + self.dtLast = self.dt + self.t = self.tLast + self.dt + self.substeps = [self.t for i in range(self.nStages)] # Manuel is ignoring different time step levels for now + #print("Hi, This is Arnob") + + + def initialize_dt(self, t0, tOut, q): + """ + Modify self.dt + """ + self.tLast = t0 + self.choose_dt() + self.t = t0 + self.dt + + def setCoefficients(self): + """ + beta are all 1's here + mwf not used right now + """ + self.alpha = np.zeros((self.nStages, self.nStages), 'd') + self.dcoefs = np.zeros((self.nStages), 'd') + + def updateStage(self): + """ + Need to switch to use coefficients + """ + self.lstage += 1 + assert self.timeOrder in [1, 2, 3] + assert self.lstage > 0 and self.lstage <= self.timeOrder + if self.timeOrder == 3: + if self.lstage == 1: + logEvent("First stage of SSP33 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + # update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] + elif self.lstage == 2: + logEvent("Second stage of SSP33 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + self.u_dof_stage[ci][self.lstage] *= old_div(1., 4.) + self.u_dof_stage[ci][self.lstage] += 3. / 4. * self.u_dof_last[ci] + # Update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] + elif self.lstage == 3: + logEvent("Third stage of SSP33 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + self.u_dof_stage[ci][self.lstage] *= old_div(2.0, 3.0) + self.u_dof_stage[ci][self.lstage] += 1.0 / 3.0 * self.u_dof_last[ci] + # update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_last[ci] + # update solution to u[0].dof + self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] + elif self.timeOrder == 2: + if self.lstage == 1: + logEvent("First stage of SSP22 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + # Update u_dof_old + self.transport.u_dof_old[:] = self.transport.u[ci].dof + elif self.lstage == 2: + logEvent("Second stage of SSP22 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + self.u_dof_stage[ci][self.lstage][:] *= old_div(1., 2.) + self.u_dof_stage[ci][self.lstage][:] += 1. / 2. * self.u_dof_last[ci] + # update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_last[ci] + # update solution to u[0].dof + self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] + else: + assert self.timeOrder == 1 + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof[:] + self.transport.u_dof_old[:] = self.transport.u[ci].dof + #self.print("Hi, Arnob") + + def initializeTimeHistory(self, resetFromDOF=True): + """ + Push necessary information into time history arrays + """ + for ci in range(self.nc): + self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] + for k in range(self.nStages): + self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] + + def updateTimeHistory(self, resetFromDOF=False): + """ + assumes successful step has been taken + """ + + self.t = self.tLast + self.dt + for ci in range(self.nc): + self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] + for k in range(self.nStages): + self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] + self.lstage = 0 + self.dtLast = self.dt + self.tLast = self.t + + def generateSubsteps(self, tList): + """ + create list of substeps over time values given in tList. These correspond to stages + """ + self.substeps = [] + tLast = self.tLast + for t in tList: + dttmp = t - tLast + self.substeps.extend([tLast + dttmp for i in range(self.nStages)]) + tLast = t + + def resetOrder(self, order): + """ + initialize data structures for stage updges + """ + self.timeOrder = order # order of approximation + self.nStages = order # number of stages total + self.lstage = 0 # last stage completed + # storage vectors + # per component stage values, list with array at each stage + self.u_dof_stage = {} + for ci in range(self.nc): + if ('m', ci) in self.transport.q: + self.u_dof_stage[ci] = [] + for k in range(self.nStages + 1): + self.u_dof_stage[ci].append(self.transport.u[ci].dof.copy()) + self.substeps = [self.t for i in range(self.nStages)] + + def setFromOptions(self, nOptions): + """ + allow classes to set various numerical parameters + """ + if 'runCFL' in dir(nOptions): + self.runCFL = nOptions.runCFL + flags = ['timeOrder'] + for flag in flags: + if flag in dir(nOptions): + val = getattr(nOptions, flag) + setattr(self, flag, val) + if flag == 'timeOrder': + self.resetOrder(self.timeOrder) + + + +class Coefficients(proteus.TransportCoefficients.TC_base): + """ + version of Re where element material type id's used in evals + """ + from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2 + from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchten_sd_het + def __init__(self, + nd, + Ksw_types, + vgm_n_types, + vgm_alpha_types, + thetaR_types, + thetaSR_types, + gravity, + density, + beta, + diagonal_conductivity=True, + getSeepageFace=None, + # FOR EDGE BASED EV + STABILIZATION_TYPE=0, + ENTROPY_TYPE=2, # logarithmic + LUMPED_MASS_MATRIX=False, + MONOLITHIC=True, + FCT=True, + num_fct_iter=1, + # FOR ENTROPY VISCOSITY + cE=1.0, + uL=0.0, + uR=1.0, + # FOR ARTIFICIAL COMPRESSION + cK=1.0, + # OUTPUT quantDOFs + outputQuantDOFs=False, ): + self.anb_seepage_flux= 0.00 + #self.anb_seepage_flux_n =0.0 + variableNames=['pressure_head'] + nc=1 + mass={0:{0:'nonlinear'}} + advection={0:{0:'nonlinear'}} + diffusion={0:{0:{0:'nonlinear'}}} + potential={0:{0:'u'}} + reaction={0:{0:'linear'}} + hamiltonian={} + self.getSeepageFace=getSeepageFace + self.gravity=gravity + self.rho = density + self.beta=beta + self.vgm_n_types = vgm_n_types + self.vgm_alpha_types = vgm_alpha_types + self.thetaR_types = thetaR_types + self.thetaSR_types = thetaSR_types + self.elementMaterialTypes = None + self.exteriorElementBoundaryTypes = None + self.materialTypes_q = None + self.materialTypes_ebq = None + self.materialTypes_ebqe = None + self.nd = nd + self.nMaterialTypes = len(thetaR_types) + self.q = {}; self.ebqe = {}; self.ebq = {}; self.ebq_global={} + #try to allow some flexibility in input of permeability/conductivity tensor + self.diagonal_conductivity = diagonal_conductivity + self.Ksw_types_in = Ksw_types + if self.diagonal_conductivity: + sparseDiffusionTensors = {(0,0):(np.arange(self.nd+1,dtype='i'), + np.arange(self.nd,dtype='i'))} + + assert len(Ksw_types.shape) in [1,2], "if diagonal conductivity true then Ksw_types scalar or vector of diagonal entries" + #allow scalar input Ks + if len(Ksw_types.shape)==1: + self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd),'d') + for I in range(self.nd): + self.Ksw_types[:,I] = Ksw_types + else: + self.Ksw_types = Ksw_types + else: #full + sparseDiffusionTensors = {(0,0):(np.arange(self.nd**2+1,step=self.nd,dtype='i'), + np.array([list(range(self.nd)) for row in range(self.nd)],dtype='i'))} + assert len(Ksw_types.shape) in [1,2], "if full tensor conductivity true then Ksw_types scalar or 'flattened' row-major representation of entries" + if len(Ksw_types.shape)==1: + self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd**2),'d') + for I in range(self.nd): + self.Ksw_types[:,I*self.nd+I] = Ksw_types + else: + assert Ksw_types.shape[1] == self.nd**2 + self.Ksw_types = Ksw_types + # EDGE BASED (AND ENTROPY) VISCOSITY + self.LUMPED_MASS_MATRIX = LUMPED_MASS_MATRIX + self.MONOLITHIC = MONOLITHIC + self.STABILIZATION_TYPE = STABILIZATION_TYPE + self.ENTROPY_TYPE = ENTROPY_TYPE + self.FCT = FCT + self.num_fct_iter=num_fct_iter + self.uL = uL + self.uR = uR + self.cK = cK + self.forceStrongConditions = True + self.cE = cE + self.outputQuantDOFs = outputQuantDOFs + TC_base.__init__(self, + nc, + mass, + advection, + diffusion, + potential, + reaction, + hamiltonian, + variableNames, + sparseDiffusionTensors = sparseDiffusionTensors, + useSparseDiffusion = True) + + def initializeMesh(self,mesh): + from proteus.SubsurfaceTransportCoefficients import BlockHeterogeneousCoefficients + self.elementMaterialTypes,self.exteriorElementBoundaryTypes,self.elementBoundaryTypes = BlockHeterogeneousCoefficients(mesh).initializeMaterialTypes() + #want element boundary material types for evaluating heterogeneity + #not boundary conditions + self.isSeepageFace = np.zeros((mesh.nExteriorElementBoundaries_global),'i') + if self.getSeepageFace != None: + for ebNE in range(mesh.nExteriorElementBoundaries_global): + #mwf missing ebNE-->ebN? + ebN = mesh.exteriorElementBoundariesArray[ebNE] + #print "eb flag",mesh.elementBoundaryMaterialTypes[ebN] + #print("Hi, Arnob") + #print self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) + self.isSeepageFace[ebNE] = self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) + #print (self.isSeepageFace) + def initializeElementQuadrature(self,t,cq): + self.materialTypes_q = self.elementMaterialTypes + self.q_shape = cq[('u',0)].shape + #self.anb_seepage_flux= anb_seepage_flux + #print("The seepage is ", anb_seepage_flux) +# cq['Ks'] = np.zeros(self.q_shape,'d') +# for k in range(self.q_shape[1]): +# cq['Ks'][:,k] = self.Ksw_types[self.elementMaterialTypes,0] + self.q[('vol_frac',0)] = np.zeros(self.q_shape,'d') + def initializeElementBoundaryQuadrature(self,t,cebq,cebq_global): + self.materialTypes_ebq = np.zeros(cebq[('u',0)].shape[0:2],'i') + self.ebq_shape = cebq[('u',0)].shape + for ebN_local in range(self.ebq_shape[1]): + self.materialTypes_ebq[:,ebN_local] = self.elementMaterialTypes + self.ebq[('vol_frac',0)] = np.zeros(self.ebq_shape,'d') + + def initializeGlobalExteriorElementBoundaryQuadrature(self,t,cebqe): + self.materialTypes_ebqe = self.exteriorElementBoundaryTypes + self.ebqe_shape = cebqe[('u',0)].shape + self.ebqe[('vol_frac',0)] = np.zeros(self.ebqe_shape,'d') + # + + + def evaluate(self,t,c): + if c[('u',0)].shape == self.q_shape: + materialTypes = self.materialTypes_q + vol_frac = self.q[('vol_frac',0)] + elif c[('u',0)].shape == self.ebqe_shape: + materialTypes = self.materialTypes_ebqe + vol_frac = self.ebqe[('vol_frac',0)] + elif c[('u',0)].shape == self.ebq_shape: + materialTypes = self.materialTypes_ebq + vol_frac = self.ebq[('vol_frac',0)] + else: + assert False, "no materialType found to match c[('u',0)].shape= %s " % c[('u',0)].shape + self.conservativeHeadRichardsMualemVanGenuchten_sd_het(self.sdInfo[(0,0)][0], + self.sdInfo[(0,0)][1], + materialTypes, + self.rho, + self.beta, + self.gravity, + self.vgm_alpha_types, + self.vgm_n_types, + self.thetaR_types, + self.thetaSR_types, + self.Ksw_types, + c[('u',0)], + c[('m',0)], + c[('dm',0,0)], + c[('f',0)], + c[('df',0,0)], + c[('a',0,0)], + c[('da',0,0,0)], + vol_frac) + # print "Picard---------------------------------------------------------------" + # c[('df',0,0)][:] = 0.0 + # c[('da',0,0,0)][:] = 0.0 +# self.conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2(materialTypes, +# self.rho, +# self.beta, +# self.gravity, +# self.vgm_alpha_types, +# self.vgm_n_types, +# self.thetaR_types, +# self.thetaSR_types, +# self.Ksw_types, +# c[('u',0)], +# c[('m',0)], +# c[('dm',0,0)], +# c[('f',0)], +# c[('df',0,0)], +# c[('a',0,0)], +# c[('da',0,0,0)]) + #mwf debug + if (np.isnan(c[('da',0,0,0)]).any() or + np.isnan(c[('a',0,0)]).any() or + np.isnan(c[('df',0,0)]).any() or + np.isnan(c[('f',0)]).any() or + np.isnan(c[('u',0)]).any() or + np.isnan(c[('m',0)]).any() or + np.isnan(c[('dm',0,0)]).any()): + import pdb + pdb.set_trace() + + def postStep(self, t, firstStep=False): + # #anb_seepage_flux_n[:]= self.anb_seepage_flux + with open('seepage_stab_0', "a") as f: + # f.write("\n Time"+ ",\t" +"Seepage\n") + f.write(repr(t)+ ",\t")# +repr(np.sum(self.LevelModel.anb_seepage_flux_n))) + +class LevelModel(proteus.Transport.OneLevelTransport): + nCalls=0 + def __init__(self, + uDict, + phiDict, + testSpaceDict, + matType, + dofBoundaryConditionsDict, + dofBoundaryConditionsSetterDict, + coefficients, + elementQuadrature, + elementBoundaryQuadrature, + fluxBoundaryConditionsDict=None, + advectiveFluxBoundaryConditionsSetterDict=None, + diffusiveFluxBoundaryConditionsSetterDictDict=None, + stressTraceBoundaryConditionsSetterDict=None, + stabilization=None, + shockCapturing=None, + conservativeFluxDict=None, + numericalFluxType=None, + TimeIntegrationClass=None, + massLumping=False, + reactionLumping=False, + options=None, + name='defaultName', + reuse_trial_and_test_quadrature=True, + sd = True, + movingDomain=False, + bdyNullSpace=False): + self.bdyNullSpace=bdyNullSpace + # + #set the objects describing the method and boundary conditions + # + self.movingDomain=movingDomain + self.tLast_mesh=None + # + self.name=name + self.sd=sd + self.Hess=False + self.lowmem=True + self.timeTerm=True#allow turning off the time derivative + #self.lowmem=False + self.testIsTrial=True + self.phiTrialIsTrial=True + self.u = uDict + self.ua = {}#analytical solutions + self.phi = phiDict + self.dphi={} + self.matType = matType + #mwf try to reuse test and trial information across components if spaces are the same + self.reuse_test_trial_quadrature = reuse_trial_and_test_quadrature#True#False + if self.reuse_test_trial_quadrature: + for ci in range(1,coefficients.nc): + assert self.u[ci].femSpace.__class__.__name__ == self.u[0].femSpace.__class__.__name__, "to reuse_test_trial_quad all femSpaces must be the same!" + self.u_dof_old = None + ## Simplicial Mesh + self.mesh = self.u[0].femSpace.mesh #assume the same mesh for all components for now + self.testSpace = testSpaceDict + self.dirichletConditions = dofBoundaryConditionsDict + self.dirichletNodeSetList=None #explicit Dirichlet conditions for now, no Dirichlet BC constraints + self.coefficients = coefficients + self.coefficients.initializeMesh(self.mesh) + self.nc = self.coefficients.nc + self.stabilization = stabilization + self.shockCapturing = shockCapturing + self.conservativeFlux = conservativeFluxDict #no velocity post-processing for now + self.fluxBoundaryConditions=fluxBoundaryConditionsDict + self.advectiveFluxBoundaryConditionsSetterDict=advectiveFluxBoundaryConditionsSetterDict + self.diffusiveFluxBoundaryConditionsSetterDictDict = diffusiveFluxBoundaryConditionsSetterDictDict + #determine whether the stabilization term is nonlinear + self.stabilizationIsNonlinear = False + #cek come back + if self.stabilization != None: + for ci in range(self.nc): + if ci in coefficients.mass: + for flag in list(coefficients.mass[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.advection: + for flag in list(coefficients.advection[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.diffusion: + for diffusionDict in list(coefficients.diffusion[ci].values()): + for flag in list(diffusionDict.values()): + if flag != 'constant': + self.stabilizationIsNonlinear=True + if ci in coefficients.potential: + for flag in list(coefficients.potential[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.reaction: + for flag in list(coefficients.reaction[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.hamiltonian: + for flag in list(coefficients.hamiltonian[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + #determine if we need element boundary storage + self.elementBoundaryIntegrals = {} + for ci in range(self.nc): + self.elementBoundaryIntegrals[ci] = ((self.conservativeFlux != None) or + (numericalFluxType != None) or + (self.fluxBoundaryConditions[ci] == 'outFlow') or + (self.fluxBoundaryConditions[ci] == 'mixedFlow') or + (self.fluxBoundaryConditions[ci] == 'setFlow')) + # + #calculate some dimensions + # + self.nSpace_global = self.u[0].femSpace.nSpace_global #assume same space dim for all variables + self.nDOF_trial_element = [u_j.femSpace.max_nDOF_element for u_j in list(self.u.values())] + self.nDOF_phi_trial_element = [phi_k.femSpace.max_nDOF_element for phi_k in list(self.phi.values())] + self.n_phi_ip_element = [phi_k.femSpace.referenceFiniteElement.interpolationConditions.nQuadraturePoints for phi_k in list(self.phi.values())] + self.nDOF_test_element = [femSpace.max_nDOF_element for femSpace in list(self.testSpace.values())] + self.nFreeDOF_global = [dc.nFreeDOF_global for dc in list(self.dirichletConditions.values())] + self.nVDOF_element = sum(self.nDOF_trial_element) + self.nFreeVDOF_global = sum(self.nFreeDOF_global) + # + NonlinearEquation.__init__(self,self.nFreeVDOF_global) + # + #build the quadrature point dictionaries from the input (this + #is just for convenience so that the input doesn't have to be + #complete) + # + elementQuadratureDict={} + elemQuadIsDict = isinstance(elementQuadrature,dict) + if elemQuadIsDict: #set terms manually + for I in self.coefficients.elementIntegralKeys: + if I in elementQuadrature: + elementQuadratureDict[I] = elementQuadrature[I] + + else: + elementQuadratureDict[I] = elementQuadrature['default'] + else: + for I in self.coefficients.elementIntegralKeys: + elementQuadratureDict[I] = elementQuadrature + if self.stabilization != None: + for I in self.coefficients.elementIntegralKeys: + if elemQuadIsDict: + if I in elementQuadrature: + elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature[I] + else: + elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature['default'] + else: + elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature + if self.shockCapturing != None: + for ci in self.shockCapturing.components: + if elemQuadIsDict: + if ('numDiff',ci,ci) in elementQuadrature: + elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature[('numDiff',ci,ci)] + #print("Hi, Arnob1") + #print(anb_seepage_flux) + else: + elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature['default'] + #print("Hi, Arnob2") + #print(anb_seepage_flux) + else: + elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature + print("Hi, Arnob3") + #print(anb_seepage_flux) + if massLumping: + for ci in list(self.coefficients.mass.keys()): + elementQuadratureDict[('m',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + print("Hi, Arnob4") + #print(anb_seepage_flux) + for I in self.coefficients.elementIntegralKeys: + elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + print("Hi, Arnob5") + #print(anb_seepage_flux) + if reactionLumping: + for ci in list(self.coefficients.mass.keys()): + elementQuadratureDict[('r',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + print("Hi, Arnob6") + #print(anb_seepage_flux) + for I in self.coefficients.elementIntegralKeys: + elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + print("Hi, Arnob7") + #print(anb_seepage_flux) + elementBoundaryQuadratureDict={} + if isinstance(elementBoundaryQuadrature,dict): #set terms manually + for I in self.coefficients.elementBoundaryIntegralKeys: + if I in elementBoundaryQuadrature: + elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature[I] + print("Hi, Arnob8") + #print(anb_seepage_flux) + else: + elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature['default'] + #print("Hi, Arnob9") + #print(anb_seepage_flux) + else: + for I in self.coefficients.elementBoundaryIntegralKeys: + elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature + print("Hi, Arnob10") + #print(anb_seepage_flux) + # + # find the union of all element quadrature points and + # build a quadrature rule for each integral that has a + # weight at each point in the union + #mwf include tag telling me which indices are which quadrature rule? + (self.elementQuadraturePoints,self.elementQuadratureWeights, + self.elementQuadratureRuleIndeces) = Quadrature.buildUnion(elementQuadratureDict) + self.nQuadraturePoints_element = self.elementQuadraturePoints.shape[0] + self.nQuadraturePoints_global = self.nQuadraturePoints_element*self.mesh.nElements_global + # + #Repeat the same thing for the element boundary quadrature + # + (self.elementBoundaryQuadraturePoints, + self.elementBoundaryQuadratureWeights, + self.elementBoundaryQuadratureRuleIndeces) = Quadrature.buildUnion(elementBoundaryQuadratureDict) + self.nElementBoundaryQuadraturePoints_elementBoundary = self.elementBoundaryQuadraturePoints.shape[0] + self.nElementBoundaryQuadraturePoints_global = (self.mesh.nElements_global* + self.mesh.nElementBoundaries_element* + self.nElementBoundaryQuadraturePoints_elementBoundary) +# if isinstance(self.u[0].femSpace,C0_AffineLinearOnSimplexWithNodalBasis): +# print self.nQuadraturePoints_element +# if self.nSpace_global == 3: +# assert(self.nQuadraturePoints_element == 5) +# elif self.nSpace_global == 2: +# assert(self.nQuadraturePoints_element == 6) +# elif self.nSpace_global == 1: +# assert(self.nQuadraturePoints_element == 3) +# +# print self.nElementBoundaryQuadraturePoints_elementBoundary +# if self.nSpace_global == 3: +# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) +# elif self.nSpace_global == 2: +# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) +# elif self.nSpace_global == 1: +# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 1) + + # + #storage dictionaries + self.scalars_element = set() + # + #simplified allocations for test==trial and also check if space is mixed or not + # + self.q={} + self.ebq={} + self.ebq_global={} + self.ebqe={} + self.phi_ip={} + self.edge_based_cfl = np.zeros(self.u[0].dof.shape)+100 + #mesh + #self.q['x'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,3),'d') + self.q[('dV_u', 0)] = (old_div(1.0, self.mesh.nElements_global)) * np.ones((self.mesh.nElements_global, self.nQuadraturePoints_element), 'd') + self.ebqe['x'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,3),'d') + self.q[('u',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') + self.q[('grad(u)',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') + self.q['velocity'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') + self.q[('m',0)] = self.q[('u',0)].copy() + self.q[('mt',0)] = self.q[('u',0)].copy() + self.q[('m_last',0)] = self.q[('u',0)].copy() + self.q[('m_tmp',0)] = self.q[('u',0)].copy() + self.q[('cfl',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') + self.q[('numDiff',0,0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') + self.ebqe[('u',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.ebqe[('grad(u)',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') + self.ebqe['velocity'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') + self.ebqe[('advectiveFlux_bc_flag',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'i') + self.ebqe[('advectiveFlux_bc',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.ebqe[('advectiveFlux',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.ebqe[('penalty')] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.points_elementBoundaryQuadrature= set() + self.scalars_elementBoundaryQuadrature= set([('u',ci) for ci in range(self.nc)]) + self.vectors_elementBoundaryQuadrature= set() + self.tensors_elementBoundaryQuadrature= set() + self.inflowBoundaryBC = {} + self.inflowBoundaryBC_values = {} + self.inflowFlux = {} + for cj in range(self.nc): + self.inflowBoundaryBC[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,),'i') + self.inflowBoundaryBC_values[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nDOF_trial_element[cj]),'d') + self.inflowFlux[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.internalNodes = set(range(self.mesh.nNodes_global)) + #identify the internal nodes this is ought to be in mesh + ##\todo move this to mesh + for ebNE in range(self.mesh.nExteriorElementBoundaries_global): + ebN = self.mesh.exteriorElementBoundariesArray[ebNE] + eN_global = self.mesh.elementBoundaryElementsArray[ebN,0] + ebN_element = self.mesh.elementBoundaryLocalElementBoundariesArray[ebN,0] + for i in range(self.mesh.nNodes_element): + if i != ebN_element: + I = self.mesh.elementNodesArray[eN_global,i] + self.internalNodes -= set([I]) + self.nNodes_internal = len(self.internalNodes) + self.internalNodesArray=np.zeros((self.nNodes_internal,),'i') + for nI,n in enumerate(self.internalNodes): + self.internalNodesArray[nI]=n + # + del self.internalNodes + self.internalNodes = None + logEvent("Updating local to global mappings",2) + self.updateLocal2Global() + logEvent("Building time integration object",2) + logEvent(memory("inflowBC, internalNodes,updateLocal2Global","OneLevelTransport"),level=4) + #mwf for interpolating subgrid error for gradients etc + if self.stabilization and self.stabilization.usesGradientStabilization: + self.timeIntegration = TimeIntegrationClass(self,integrateInterpolationPoints=True) + else: + self.timeIntegration = TimeIntegrationClass(self) + + if options != None: + self.timeIntegration.setFromOptions(options) + logEvent(memory("TimeIntegration","OneLevelTransport"),level=4) + logEvent("Calculating numerical quadrature formulas",2) + self.calculateQuadrature() + #lay out components/equations contiguously for now + self.offset = [0] + for ci in range(1,self.nc): + self.offset += [self.offset[ci-1]+self.nFreeDOF_global[ci-1]] + self.stride = [1 for ci in range(self.nc)] + #use contiguous layout of components for parallel, requires weak DBC's + # mql. Some ASSERTS to restrict the combination of the methods + if self.coefficients.STABILIZATION_TYPE > 0: + pass + #assert self.timeIntegration.isSSP == True, "If STABILIZATION_TYPE>0, use RKEV timeIntegration within VOF model" + #cond = 'levelNonlinearSolver' in dir(options) and (options.levelNonlinearSolver == + # ExplicitLumpedMassMatrixForRichards or options.levelNonlinearSolver == ExplicitConsistentMassMatrixForRichards) + #assert cond, "If STABILIZATION_TYPE>0, use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards or ExplicitConsistentMassMatrixForRichards" + try: + if 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards: + assert self.coefficients.LUMPED_MASS_MATRIX, "If levelNonlinearSolver=ExplicitLumpedMassMatrix, use LUMPED_MASS_MATRIX=True" + except: + pass + if self.coefficients.LUMPED_MASS_MATRIX == True: + cond = self.coefficients.STABILIZATION_TYPE == 2 + assert cond, "Use lumped mass matrix just with: STABILIZATION_TYPE=2 (smoothness based stab.)" + cond = 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards + assert cond, "Use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards when the mass matrix is lumped" + + ################################################################# + ####################ARNOB_FCT_EDIT############################### + ################################################################# + + if self.coefficients.LUMPED_MASS_MATRIX == False: + cond = self.coefficients.STABILIZATION_TYPE == 2 + assert cond, "Use lumped mass matrix just with: STABILIZATION_TYPE=2 (smoothness based stab.)" + cond = 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == Newton + #assert cond, "Use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards when the mass matrix is lumped" + + + + + + if self.coefficients.FCT == True: + cond = self.coefficients.STABILIZATION_TYPE > 0, "Use FCT just with STABILIZATION_TYPE>0; i.e., edge based stabilization" + # END OF ASSERTS + + # cek adding empty data member for low order numerical viscosity structures here for now + self.ML = None # lumped mass matrix + self.MC_global = None # consistent mass matrix + self.cterm_global = None + self.cterm_transpose_global = None + # dL_global and dC_global are not the full matrices but just the CSR arrays containing the non zero entries + self.residualComputed=False #TMP + self.dLow= None + self.fluxMatrix = None + self.uDotLow = None + self.uLow = None + self.dt_times_dC_minus_dL = None + self.min_s_bc = None + self.max_s_bc = None + # Aux quantity at DOFs to be filled by optimized code (MQL) + self.quantDOFs = np.zeros(self.u[0].dof.shape, 'd') + self.sLow = np.zeros(self.u[0].dof.shape, 'd') + self.sHigh = np.zeros(self.u[0].dof.shape, 'd') + self.sn = np.zeros(self.u[0].dof.shape, 'd') + self.anb_seepage_flux_n = np.zeros(self.u[0].dof.shape, 'd') + comm = Comm.get() + self.comm=comm + if comm.size() > 1: + assert numericalFluxType != None and numericalFluxType.useWeakDirichletConditions,"You must use a numerical flux to apply weak boundary conditions for parallel runs" + self.offset = [0] + for ci in range(1,self.nc): + self.offset += [ci] + self.stride = [self.nc for ci in range(self.nc)] + # + logEvent(memory("stride+offset","OneLevelTransport"),level=4) + + + if numericalFluxType != None: + if options is None or options.periodicDirichletConditions is None: + self.numericalFlux = numericalFluxType(self, + dofBoundaryConditionsSetterDict, + advectiveFluxBoundaryConditionsSetterDict, + diffusiveFluxBoundaryConditionsSetterDictDict) + else: + self.numericalFlux = numericalFluxType(self, + dofBoundaryConditionsSetterDict, + advectiveFluxBoundaryConditionsSetterDict, + diffusiveFluxBoundaryConditionsSetterDictDict, + options.periodicDirichletConditions) + else: + self.numericalFlux = None + #set penalty terms + #cek todo move into numerical flux initialization + if 'penalty' in self.ebq_global: + for ebN in range(self.mesh.nElementBoundaries_global): + for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): + self.ebq_global['penalty'][ebN,k] = old_div(self.numericalFlux.penalty_constant,(self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power)) + #penalty term + #cek move to Numerical flux initialization + if 'penalty' in self.ebqe: + for ebNE in range(self.mesh.nExteriorElementBoundaries_global): + ebN = self.mesh.exteriorElementBoundariesArray[ebNE] + for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): + self.ebqe['penalty'][ebNE,k] = old_div(self.numericalFlux.penalty_constant,self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power) + logEvent(memory("numericalFlux","OneLevelTransport"),level=4) + self.elementEffectiveDiametersArray = self.mesh.elementInnerDiametersArray + #use post processing tools to get conservative fluxes, None by default + from proteus import PostProcessingTools + self.velocityPostProcessor = PostProcessingTools.VelocityPostProcessingChooser(self) + logEvent(memory("velocity postprocessor","OneLevelTransport"),level=4) + #helper for writing out data storage + from proteus import Archiver + self.elementQuadratureDictionaryWriter = Archiver.XdmfWriter() + self.elementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() + self.exteriorElementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() + #TODO get rid of this + for ci,fbcObject in list(self.fluxBoundaryConditionsObjectsDict.items()): + self.ebqe[('advectiveFlux_bc_flag',ci)] = np.zeros(self.ebqe[('advectiveFlux_bc',ci)].shape,'i') + for t,g in list(fbcObject.advectiveFluxBoundaryConditionsDict.items()): + if ci in self.coefficients.advection: + self.ebqe[('advectiveFlux_bc',ci)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) + self.ebqe[('advectiveFlux_bc_flag',ci)][t[0],t[1]] = 1 + + if hasattr(self.numericalFlux,'setDirichletValues'): + self.numericalFlux.setDirichletValues(self.ebqe) + if not hasattr(self.numericalFlux,'isDOFBoundary'): + self.numericalFlux.isDOFBoundary = {0:np.zeros(self.ebqe[('u',0)].shape,'i')} + if not hasattr(self.numericalFlux,'ebqe'): + self.numericalFlux.ebqe = {('u',0):np.zeros(self.ebqe[('u',0)].shape,'d')} + #TODO how to handle redistancing calls for calculateCoefficients,calculateElementResidual etc + self.globalResidualDummy = None + compKernelFlag=0 + self.delta_x_ij=None + self.richards = cRichards_base(self.nSpace_global, + self.nQuadraturePoints_element, + self.u[0].femSpace.elementMaps.localFunctionSpace.dim, + self.u[0].femSpace.referenceFiniteElement.localFunctionSpace.dim, + self.testSpace[0].referenceFiniteElement.localFunctionSpace.dim, + self.nElementBoundaryQuadraturePoints_elementBoundary, + compKernelFlag) + if self.movingDomain: + self.MOVING_DOMAIN=1.0 + else: + self.MOVING_DOMAIN=0.0 + #cek hack + self.movingDomain=False + self.MOVING_DOMAIN=0.0 + if self.mesh.nodeVelocityArray is None: + self.mesh.nodeVelocityArray = np.zeros(self.mesh.nodeArray.shape,'d') + self.forceStrongConditions=True + self.dirichletConditionsForceDOF = {} + if self.forceStrongConditions: + for cj in range(self.nc): + self.dirichletConditionsForceDOF[cj] = DOFBoundaryConditions(self.u[cj].femSpace,dofBoundaryConditionsSetterDict[cj],weakDirichletConditions=False) + def FCTStep(self): + import pdb + rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() + limited_solution = np.zeros((len(rowptr) - 1),'d') + #self.u_free_dof_stage_0_l = np.zeros((len(rowptr) - 1),'d') + #self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage], # soln + #fromFreeToGlobal=0 + #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + # self.offset[0], + # self.stride[0], + # self.dirichletConditions[0].global2freeGlobal_global_dofs, + # self.dirichletConditions[0].global2freeGlobal_free_dofs, + # self.u_free_dof_stage_0_l, + # self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage]) + argsDict = cArgumentsDict.ArgumentsDict() + argsDict["bc_mask"] = self.bc_mask + argsDict["NNZ"] = self.nnz + argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs + argsDict["dt"] = self.timeIntegration.dt + argsDict["lumped_mass_matrix"] = self.ML + argsDict["soln"] = self.sn + argsDict["pn"] = self.u[0].dof + argsDict["solH"] = self.sHigh + argsDict["uLow"] = self.sLow + argsDict["uDotLow"] = self.uDotLow + argsDict["limited_solution"] = limited_solution + argsDict["csrRowIndeces_DofLoops"] = rowptr + argsDict["csrColumnOffsets_DofLoops"] = colind + argsDict["MassMatrix"] = MassMatrix + argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL + argsDict["min_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0]) #cek hack just set from physical bounds + argsDict["max_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0] + self.coefficients.thetaSR_types[0]) #cek hack + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["MONOLITHIC"] =0#cek hack self.coefficients.MONOLITHIC + argsDict["anb_seepage_flux_n"]= self.anb_seepage_flux_n + #pdb.set_trace() + self.richards.FCTStep(argsDict) + + # self.nnz, # number of non zero entries + # len(rowptr) - 1, # number of DOFs + # self.timeIntegration.dt, + # self.ML, # Lumped mass matrix + # self.sn, + # self.u_dof_old, + # self.sHigh, # high order solution + # self.sLow, + # limited_solution, + # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) + # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) + # MassMatrix, + # self.dt_times_dC_minus_dL, + # self.min_s_bc, + # self.max_s_bc, + # self.coefficients.LUMPED_MASS_MATRIX, + # self.coefficients.MONOLITHIC) + old_dof = self.u[0].dof.copy() + self.invert(limited_solution, self.u[0].dof) + self.timeIntegration.u[:] = self.u[0].dof + #fromFreeToGlobal=1 #direction copying + #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + # self.offset[0], + # self.stride[0], + # self.dirichletConditions[0].global2freeGlobal_global_dofs, + # self.dirichletConditions[0].global2freeGlobal_free_dofs, + # self.u[0].dof, + # limited_solution) + def kth_FCT_step(self): + #import pdb + #pdb.set_trace() + rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() + limitedFlux = np.zeros(self.nnz) + limited_solution = np.zeros((len(rowptr) - 1),'d') + #limited_solution[:] = self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage] + fromFreeToGlobal=0 #direction copying + cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + self.offset[0], + self.stride[0], + self.dirichletConditions[0].global2freeGlobal_global_dofs, + self.dirichletConditions[0].global2freeGlobal_free_dofs, + limited_solution, + self.timeintegration.u_dof_stage[0][self.timeIntegration.lstage]) + + self.richards.kth_FCT_step( + self.timeIntegration.dt, + self.coefficients.num_fct_iter, + self.nnz, # number of non zero entries + len(rowptr) - 1, # number of DOFs + MassMatrix, + self.ML, # Lumped mass matrix + self.u_dof_old, + limited_solution, + self.uDotLow, + self.uLow, + self.dLow, + self.fluxMatrix, + limitedFlux, + rowptr, + colind) + + self.timeIntegration.u[:] = limited_solution + #self.u[0].dof[:] = limited_solution + fromFreeToGlobal=1 #direction copying + cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + self.offset[0], + self.stride[0], + self.dirichletConditions[0].global2freeGlobal_global_dofs, + self.dirichletConditions[0].global2freeGlobal_free_dofs, + self.u[0].dof, + limited_solution) + def calculateCoefficients(self): + pass + def calculateElementResidual(self): + if self.globalResidualDummy != None: + self.getResidual(self.u[0].dof,self.globalResidualDummy) + def getResidual(self,u,r): + import pdb + import copy + """ + Calculate the element residuals and add in to the global residual + """ + cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, + self.jacobian) + if self.u_dof_old is None: + # Pass initial condition to u_dof_old + self.u_dof_old = np.copy(self.u[0].dof) + rowptr, colind, nzval = self.jacobian.getCSRrepresentation() + nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix + r.fill(0.0) + ######################## + ### COMPUTE C MATRIX ### + ######################## + if self.cterm_global is None: + # since we only need cterm_global to persist, we can drop the other self.'s + self.cterm = {} + self.cterm_a = {} + self.cterm_global = {} + self.cterm_transpose = {} + self.cterm_a_transpose = {} + self.cterm_global_transpose = {} + rowptr, colind, nzval = self.jacobian.getCSRrepresentation() + nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix + di = self.q[('grad(u)', 0)].copy() # direction of derivative + # JACOBIANS (FOR ELEMENT TRANSFORMATION) + self.q[('J')] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nSpace_global, + self.nSpace_global), + 'd') + self.q[('inverse(J)')] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nSpace_global, + self.nSpace_global), + 'd') + self.q[('det(J)')] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element), + 'd') + self.u[0].femSpace.elementMaps.getJacobianValues(self.elementQuadraturePoints, + self.q['J'], + self.q['inverse(J)'], + self.q['det(J)']) + self.q['abs(det(J))'] = np.abs(self.q['det(J)']) + # SHAPE FUNCTIONS + self.q[('w', 0)] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nDOF_test_element[0]), + 'd') + self.q[('w*dV_m', 0)] = self.q[('w', 0)].copy() + self.u[0].femSpace.getBasisValues(self.elementQuadraturePoints, self.q[('w', 0)]) + cfemIntegrals.calculateWeightedShape(self.elementQuadratureWeights[('u', 0)], + self.q['abs(det(J))'], + self.q[('w', 0)], + self.q[('w*dV_m', 0)]) + # GRADIENT OF TEST FUNCTIONS + self.q[('grad(w)', 0)] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nDOF_test_element[0], + self.nSpace_global), + 'd') + self.u[0].femSpace.getBasisGradientValues(self.elementQuadraturePoints, + self.q['inverse(J)'], + self.q[('grad(w)', 0)]) + self.q[('grad(w)*dV_f', 0)] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nDOF_test_element[0], + self.nSpace_global), + 'd') + cfemIntegrals.calculateWeightedShapeGradients(self.elementQuadratureWeights[('u', 0)], + self.q['abs(det(J))'], + self.q[('grad(w)', 0)], + self.q[('grad(w)*dV_f', 0)]) + ########################## + ### LUMPED MASS MATRIX ### + ########################## + # assume a linear mass term + dm = np.ones(self.q[('u', 0)].shape, 'd') + elementMassMatrix = np.zeros((self.mesh.nElements_global, + self.nDOF_test_element[0], + self.nDOF_trial_element[0]), 'd') + cfemIntegrals.updateMassJacobian_weak_lowmem(dm, + self.q[('w', 0)], + self.q[('w*dV_m', 0)], + elementMassMatrix) + self.MC_a = nzval.copy() + self.MC_global = SparseMat(self.nFreeDOF_global[0], + self.nFreeDOF_global[0], + nnz, + self.MC_a, + colind, + rowptr) + cfemIntegrals.zeroJacobian_CSR(self.nnz, self.MC_global) + cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.csrRowIndeces[(0, 0)], + self.csrColumnOffsets[(0, 0)], + elementMassMatrix, + self.MC_global) + self.ML = np.zeros((self.nFreeDOF_global[0],), 'd') + for i in range(self.nFreeDOF_global[0]): + self.ML[i] = self.MC_a[rowptr[i]:rowptr[i + 1]].sum() + np.testing.assert_almost_equal(self.ML.sum(), + self.mesh.volume, + err_msg="Trace of lumped mass matrix should be the domain volume", verbose=True) + for d in range(self.nSpace_global): # spatial dimensions + # C matrices + self.cterm[d] = np.zeros((self.mesh.nElements_global, + self.nDOF_test_element[0], + self.nDOF_trial_element[0]), 'd') + self.cterm_a[d] = nzval.copy() + #self.cterm_a[d] = np.zeros(nzval.size) + self.cterm_global[d] = SparseMat(self.nFreeDOF_global[0], + self.nFreeDOF_global[0], + nnz, + self.cterm_a[d], + colind, + rowptr) + cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global[d]) + di[:] = 0.0 + di[..., d] = 1.0 + cfemIntegrals.updateHamiltonianJacobian_weak_lowmem(di, + self.q[('grad(w)*dV_f', 0)], + self.q[('w', 0)], + self.cterm[d]) # int[(di*grad(wj))*wi*dV] + cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.csrRowIndeces[(0, 0)], + self.csrColumnOffsets[(0, 0)], + self.cterm[d], + self.cterm_global[d]) + # C Transpose matrices + self.cterm_transpose[d] = np.zeros((self.mesh.nElements_global, + self.nDOF_test_element[0], + self.nDOF_trial_element[0]), 'd') + self.cterm_a_transpose[d] = nzval.copy() + self.cterm_global_transpose[d] = SparseMat(self.nFreeDOF_global[0], + self.nFreeDOF_global[0], + nnz, + self.cterm_a_transpose[d], + colind, + rowptr) + cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global_transpose[d]) + di[:] = 0.0 + di[..., d] = -1.0 + cfemIntegrals.updateAdvectionJacobian_weak_lowmem(di, + self.q[('w', 0)], + self.q[('grad(w)*dV_f', 0)], + self.cterm_transpose[d]) # -int[(-di*grad(wi))*wj*dV] + cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.csrRowIndeces[(0, 0)], + self.csrColumnOffsets[(0, 0)], + self.cterm_transpose[d], + self.cterm_global_transpose[d]) + + rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() + else: + Cy = np.zeros(Cx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() + else: + Cz = np.zeros(Cx.shape, 'd') + rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() + else: + CTy = np.zeros(CTx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() + else: + CTz = np.zeros(CTx.shape, 'd') + + # This is dummy. I just care about the csr structure of the sparse matrix + self.dLow = np.zeros(Cx.shape, 'd') + self.fluxMatrix = np.zeros(Cx.shape, 'd') + self.dt_times_dC_minus_dL = np.zeros(Cx.shape, 'd') + nFree = len(rowptr)-1 + self.min_s_bc = np.zeros(nFree, 'd') + 1E10 + self.max_s_bc = np.zeros(nFree, 'd') - 1E10 + self.uDotLow = np.zeros(nFree, 'd') + self.uLow = np.zeros(nFree, 'd') + # + # cek end computationa of cterm_global + # + # cek showing mquezada an example of using cterm_global sparse matrix + # calculation y = c*x where x==1 + # direction=0 + #rowptr, colind, c = self.cterm_global[direction].getCSRrepresentation() + #y = np.zeros((self.nFreeDOF_global[0],),'d') + #x = np.ones((self.nFreeDOF_global[0],),'d') + # ij=0 + # for i in range(self.nFreeDOF_global[0]): + # for offset in range(rowptr[i],rowptr[i+1]): + # j = colind[offset] + # y[i] += c[ij]*x[j] + # ij+=1 + #Load the unknowns into the finite element dof + self.timeIntegration.calculateCoefs() + self.timeIntegration.calculateU(u) + self.setUnknowns(self.timeIntegration.u) + #cek can put in logic to skip of BC's don't depend on t or u + #Dirichlet boundary conditions + self.numericalFlux.setDirichletValues(self.ebqe) + #flux boundary conditions + #cek hack, just using advective flux for flux BC for now + for t,g in list(self.fluxBoundaryConditionsObjectsDict[0].advectiveFluxBoundaryConditionsDict.items()): + self.ebqe[('advectiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) + self.ebqe[('advectiveFlux_bc_flag',0)][t[0],t[1]] = 1 + # for t,g in self.fluxBoundaryConditionsObjectsDict[0].diffusiveFluxBoundaryConditionsDict.iteritems(): + # self.ebqe[('diffusiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) + # self.ebqe[('diffusiveFlux_bc_flag',0)][t[0],t[1]] = 1 + #self.shockCapturing.lag=True + if self.forceStrongConditions: + self.bc_mask = np.ones_like(self.u[0].dof) + for cj in range(len(self.dirichletConditionsForceDOF)): + for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): + self.u[cj].dof[dofN] = g(self.dirichletConditionsForceDOF[cj].DOFBoundaryPointDict[dofN],self.timeIntegration.t) + self.u_dof_old[dofN] = self.u[cj].dof[dofN] + self.bc_mask[dofN] = 0.0 + degree_polynomial = 1 + try: + degree_polynomial = self.u[0].femSpace.order + except: + pass + + argsDict = cArgumentsDict.ArgumentsDict() + argsDict["bc_mask"] = self.bc_mask + argsDict["dt"] = self.timeIntegration.dt + argsDict["Theta"] = 1.0 + argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi + argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi + argsDict["mesh_dof"] = self.mesh.nodeArray + argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray + argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN + argsDict["mesh_l2g"] = self.mesh.elementNodesArray + argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] + argsDict["u_trial_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi + argsDict["u_test_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi + argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace + argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace + argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] + argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals + argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians + argsDict["nElements_global"] = self.mesh.nElements_global + argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] + argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, + argsDict["isSeepageFace"] = self.coefficients.isSeepageFace + argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] + argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] + argsDict["rho"] = self.coefficients.rho + argsDict["beta"] = self.coefficients.beta + argsDict["gravity"] = self.coefficients.gravity + argsDict["alpha"] = self.coefficients.vgm_alpha_types + argsDict["n"] = self.coefficients.vgm_n_types + argsDict["thetaR"] = self.coefficients.thetaR_types + argsDict["thetaSR"] = self.coefficients.thetaSR_types + argsDict["KWs"] = self.coefficients.Ksw_types + argsDict["useMetrics"] = 0.0 + argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf + argsDict["lag_shockCapturing"] = 0 + argsDict["shockCapturingDiffusion"] = 0.0 + argsDict["sc_uref"] = 0.0 + argsDict["sc_alpha"] = 0.0 + argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g + argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] + argsDict["elementDiameter"] = self.mesh.elementDiametersArray + argsDict["degree_polynomial"] = degree_polynomial + argsDict["u_dof"] = self.u[0].dof + argsDict["u_dof_old"] = self.u_dof_old + argsDict["velocity"] = self.q['velocity'] + argsDict["q_m"] = self.timeIntegration.m_tmp[0] + argsDict["q_u"] = self.q[('u',0)] + argsDict["q_dV"] = self.q[('dV_u',0)] + argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] + argsDict["cfl"] = self.q[('cfl',0)] + argsDict["q_numDiff_u"] = self.q[('cfl',0)] + argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] + argsDict["offset_u"] = self.offset[0] + argsDict["stride_u"] = self.stride[0] + argsDict["globalResidual"] = r + argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global + argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray + argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray + argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray + argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] + argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] + argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] + argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] + argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] + argsDict["ebqe_phi"] = self.ebqe[('u',0)] + argsDict["epsFact"] = 0.0 + argsDict["ebqe_u"] = self.ebqe[('u',0)] + argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] + argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE + # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION + argsDict["cE"] = self.coefficients.cE + argsDict["cK"] = self.coefficients.cK + # PARAMETERS FOR LOG BASED ENTROPY FUNCTION + argsDict["uL"] = self.coefficients.uL + argsDict["uR"] = self.coefficients.uR + # PARAMETERS FOR EDGE VISCOSITY + argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs + argsDict["NNZ"] = self.nnz + argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern + argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) + argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) + argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms + argsDict["globalJacobian"] = self.jacobian.getCSRrepresentation()[2] + # C matrices + argsDict["Cx"] = Cx + argsDict["Cy"] = Cy + argsDict["Cz"] = Cz + argsDict["CTx"] = CTx + argsDict["CTy"] = CTy + argsDict["CTz"] = CTz + argsDict["ML"] = self.ML + argsDict["delta_x_ij"] = self.delta_x_ij + # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE + argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE + # FLUX CORRECTED TRANSPORT + argsDict["dLow"] = self.dLow + argsDict["fluxMatrix"] = self.fluxMatrix + argsDict["uDotLow"] = self.uDotLow + argsDict["uLow"] = self.uLow + argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL + argsDict["min_s_bc"] = self.min_s_bc + argsDict["max_s_bc"] = self.max_s_bc + argsDict["quantDOFs"] = self.quantDOFs + argsDict["sLow"] = self.sLow + argsDict["sn"] = self.sn + argsDict["anb_seepage_flux_n"]= self.anb_seepage_flux_n +###################################################################################### + argsDict["pn"] = self.u[0].dof + argsDict["solH"] = self.sHigh + + rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() + argsDict["MassMatrix"] = MassMatrix + argsDict["solH"] = self.sHigh + +###################################################################################### + argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #print(anb_seepage_flux) + #argsDict["anb_seepage_flux_n"] = self.coefficients.anb_seepage_flux_n + #if np.sum(anb_seepage_flux_n)>0: + + #logEvent("Hi, this is Arnob", self.anb_seepage_flux_n[0]) + print("Seepage Flux from Python file", np.sum(self.anb_seepage_flux_n)) + seepage_text_variable= np.sum(self.anb_seepage_flux_n) + + with open('seepage_stab_0',"a" ) as f: + #f.write("\n Time"+ ",\t" +"Seepage\n") + #f.write(repr(self.coefficients.t)+ ",\t" +repr(seepage_text_variable), "\n") + f.write(repr(seepage_text_variable)+ "\n") + if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG + self.calculateResidual = self.richards.calculateResidual + self.calculateJacobian = self.richards.calculateJacobian + else: + self.calculateResidual = self.richards.calculateResidual_entropy_viscosity + self.calculateJacobian = self.richards.calculateMassMatrix + if self.delta_x_ij is None: + self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') + self.calculateResidual(argsDict) + #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] + #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf + #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] + #self.timeIntegration.calculateElementCoefficients(self.q) + if self.forceStrongConditions:# + for cj in range(len(self.dirichletConditionsForceDOF)):# + for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): + r[self.offset[cj]+self.stride[cj]*dofN] = 0 + if self.stabilization: + self.stabilization.accumulateSubgridMassHistory(self.q) + logEvent("Global residual",level=9,data=r) + self.nonlinear_function_evaluations += 1 + if self.globalResidualDummy is None: + self.globalResidualDummy = np.zeros(r.shape,'d') + + #print("Hello from the python file", self.coefficients.anb_seepage_flux) + #logEvent("Hello from the python file", self.coefficients.anb_seepage_flux") + + + + + + def invert(self,u,r): + #u=s + #r=p + import pdb + import copy + """ + Calculate the element residuals and add in to the global residual + """ + self.sHigh[:] = u + rowptr, colind, nzval = self.jacobian.getCSRrepresentation() + nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix + r.fill(0.0) + rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() + else: + Cy = np.zeros(Cx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() + else: + Cz = np.zeros(Cx.shape, 'd') + rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() + else: + CTy = np.zeros(CTx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() + else: + CTz = np.zeros(CTx.shape, 'd') + + # This is dummy. I just care about the csr structure of the sparse matrix + nFree = len(rowptr)-1 + degree_polynomial = 1 + try: + degree_polynomial = self.u[0].femSpace.order + except: + pass + if self.delta_x_ij is None: + self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') + argsDict = cArgumentsDict.ArgumentsDict() + argsDict["dt"] = self.timeIntegration.dt + argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi + argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi + argsDict["mesh_dof"] = self.mesh.nodeArray + argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray + argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN + argsDict["mesh_l2g"] = self.mesh.elementNodesArray + argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] + argsDict["u_trial_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi + argsDict["u_test_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi + argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace + argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace + argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] + argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals + argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians + argsDict["nElements_global"] = self.mesh.nElements_global + argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] + argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, + argsDict["isSeepageFace"] = self.coefficients.isSeepageFace + argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] + argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] + argsDict["rho"] = self.coefficients.rho + argsDict["beta"] = self.coefficients.beta + argsDict["gravity"] = self.coefficients.gravity + argsDict["alpha"] = self.coefficients.vgm_alpha_types + argsDict["n"] = self.coefficients.vgm_n_types + argsDict["thetaR"] = self.coefficients.thetaR_types + argsDict["thetaSR"] = self.coefficients.thetaSR_types + argsDict["KWs"] = self.coefficients.Ksw_types + argsDict["useMetrics"] = 0.0 + argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf + argsDict["lag_shockCapturing"] = 0 + argsDict["shockCapturingDiffusion"] = 0.0 + argsDict["sc_uref"] = 0.0 + argsDict["sc_alpha"] = 0.0 + argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g + argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] + argsDict["elementDiameter"] = self.mesh.elementDiametersArray + argsDict["degree_polynomial"] = degree_polynomial + argsDict["u_dof"] = u#self.u[0].dof + argsDict["u_dof_old"] = self.u[0].dof + argsDict["velocity"] = self.q['velocity'] + argsDict["q_m"] = self.timeIntegration.m_tmp[0] + argsDict["q_u"] = self.q[('u',0)] + argsDict["q_dV"] = self.q[('dV_u',0)] + argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] + argsDict["cfl"] = self.q[('cfl',0)] + argsDict["q_numDiff_u"] = self.q[('cfl',0)] + argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] + argsDict["offset_u"] = self.offset[0] + argsDict["stride_u"] = self.stride[0] + argsDict["globalResidual"] = r + argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global + argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray + argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray + argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray + argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] + argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] + argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] + argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] + argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] + argsDict["ebqe_phi"] = self.ebqe[('u',0)] + argsDict["epsFact"] = 0.0 + argsDict["ebqe_u"] = self.ebqe[('u',0)] + argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] + argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE + # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION + argsDict["cE"] = self.coefficients.cE + argsDict["cK"] = self.coefficients.cK + # PARAMETERS FOR LOG BASED ENTROPY FUNCTION + argsDict["uL"] = self.coefficients.uL + argsDict["uR"] = self.coefficients.uR + # PARAMETERS FOR EDGE VISCOSITY + argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs + argsDict["NNZ"] = self.nnz + argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern + argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) + argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) + argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms + # C matrices + argsDict["Cx"] = Cx + argsDict["Cy"] = Cy + argsDict["Cz"] = Cz + argsDict["CTx"] = CTx + argsDict["CTy"] = CTy + argsDict["CTz"] = CTz + argsDict["ML"] = self.ML + argsDict["delta_x_ij"] = self.delta_x_ij + # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE + argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE + # FLUX CORRECTED TRANSPORT + argsDict["dLow"] = self.dLow + argsDict["fluxMatrix"] = self.fluxMatrix + argsDict["uDotLow"] = self.uDotLow + argsDict["uLow"] = self.uLow + argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL + argsDict["min_s_bc"] = self.min_s_bc + argsDict["max_s_bc"] = self.max_s_bc + argsDict["quantDOFs"] = self.quantDOFs + argsDict["sLow"] = self.sLow + argsDict["sn"] = self.sn + #Arnob trying to print flux + argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #print("Hi",anb_seepage_flux) + #print("Hi Seepage Flux", self.coefficients.anb_seepage_flux) + + self.richards.invert(argsDict) + # self.timeIntegration.dt, + # self.u[0].femSpace.elementMaps.psi, + # self.u[0].femSpace.elementMaps.grad_psi, + # self.mesh.nodeArray, + # self.mesh.nodeVelocityArray, + # self.MOVING_DOMAIN, + # self.mesh.elementNodesArray, + # self.elementQuadratureWeights[('u',0)], + # self.u[0].femSpace.psi, + # self.u[0].femSpace.grad_psi, + # self.u[0].femSpace.psi, + # self.u[0].femSpace.grad_psi, + # #element boundary + # self.u[0].femSpace.elementMaps.psi_trace, + # self.u[0].femSpace.elementMaps.grad_psi_trace, + # self.elementBoundaryQuadratureWeights[('u',0)], + # self.u[0].femSpace.psi_trace, + # self.u[0].femSpace.grad_psi_trace, + # self.u[0].femSpace.psi_trace, + # self.u[0].femSpace.grad_psi_trace, + # self.u[0].femSpace.elementMaps.boundaryNormals, + # self.u[0].femSpace.elementMaps.boundaryJacobians, + # #physics + # self.mesh.nElements_global, + # self.ebqe['penalty'],#double* ebqe_penalty_ext, + # self.mesh.elementMaterialTypes,#int* elementMaterialTypes, + # self.coefficients.isSeepageFace, + # self.coefficients.sdInfo[(0,0)][0],#int* a_rowptr, + # self.coefficients.sdInfo[(0,0)][1],#int* a_colind, + # self.coefficients.rho,#double rho, + # self.coefficients.beta,#double beta, + # self.coefficients.gravity,#double* gravity, + # self.coefficients.vgm_alpha_types,#double* alpha, + # self.coefficients.vgm_n_types,#double* n, + # self.coefficients.thetaR_types,#double* thetaR, + # self.coefficients.thetaSR_types,#double* thetaSR, + # self.coefficients.Ksw_types,#double* KWs, + # False,#self.coefficients.useMetrics, + # self.timeIntegration.alpha_bdf, + # 0,#self.shockCapturing.lag, + # 0.0,#cek hack self.shockCapturing.shockCapturingFactor, + # 0.0,#self.coefficients.sc_uref, + # 0.0,#self.coefficients.sc_beta, + # self.u[0].femSpace.dofMap.l2g, + # self.l2g[0]['freeGlobal'], + # self.mesh.elementDiametersArray, + # degree_polynomial, + # self.sHigh, + # self.u_dof_old, + # self.q['velocity'],#self.coefficients.q_v, + # self.timeIntegration.m_tmp[0], + # self.q[('u',0)], + # self.timeIntegration.beta_bdf[0], + # self.q[('cfl',0)], + # self.edge_based_cfl, + # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff[0], + # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff_last[0], + # self.offset[0],self.stride[0], + # r, + # self.mesh.nExteriorElementBoundaries_global, + # self.mesh.exteriorElementBoundariesArray, + # self.mesh.elementBoundaryElementsArray, + # self.mesh.elementBoundaryLocalElementBoundariesArray, + # self.ebqe['velocity'],#self.coefficients.ebqe_v, + # self.numericalFlux.isDOFBoundary[0], + # self.numericalFlux.ebqe[('u',0)], + # self.ebqe[('advectiveFlux_bc_flag',0)], + # self.ebqe[('advectiveFlux_bc',0)], + # self.ebqe[('u',0)],#cek hack self.coefficients.ebqe_phi, + # 0.0,#cek hack self.coefficients.epsFact, + # self.ebqe[('u',0)], + # self.ebqe[('advectiveFlux',0)], + # # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION + # self.coefficients.cE, + # self.coefficients.cK, + # # PARAMETERS FOR LOG BASED ENTROPY FUNCTION + # self.coefficients.uL, + # self.coefficients.uR, + # # PARAMETERS FOR EDGE VISCOSITY + # len(rowptr) - 1, # num of DOFs + # len(Cx), # num of non-zero entries in the sparsity pattern + # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) + # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) + # self.csrRowIndeces[(0, 0)], # row indices (convenient for element loops) + # self.csrColumnOffsets[(0, 0)], # column indices (convenient for element loops) + # self.csrColumnOffsets_eb[(0, 0)], # indices for boundary terms + # # C matrices + # Cx, + # Cy, + # Cz, + # CTx, + # CTy, + # CTz, + # self.ML, + # self.delta_x_ij, + # # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + # self.coefficients.LUMPED_MASS_MATRIX, + # self.coefficients.STABILIZATION_TYPE, + # self.coefficients.ENTROPY_TYPE, + # # FLUX CORRECTED TRANSPORT + # self.dLow, + # self.fluxMatrix, + # self.uDotLow, + # self.uLow, + # self.dt_times_dC_minus_dL, + # self.min_s_bc, + # self.max_s_bc, + # self.quantDOFs) + #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] + #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf + #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] + #self.timeIntegration.calculateElementCoefficients(self.q) + #if self.forceStrongConditions:# + # for cj in range(len(self.dirichletConditionsForceDOF)):# + # for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): + # r[self.offset[cj]+self.stride[cj]*dofN] = 0 + #if self.stabilization: + # self.stabilization.accumulateSubgridMassHistory(self.q) + #logEvent("Global residual",level=9,data=r) + #self.nonlinear_function_evaluations += 1 + #if self.globalResidualDummy is None: + # self.globalResidualDummy = numpy.zeros(r.shape,'d') + def postStep(self, t, firstStep=False): + with open('seepage_flux_nnnn', "a") as f: + f.write("\n Time"+ ",\t" +"Seepage\n") + f.write(repr(t)+ ",\t" +repr(self.coefficients.anb_seepage_flux)) + def getJacobian(self,jacobian): + if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG + cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, + jacobian) + degree_polynomial = 1 + try: + degree_polynomial = self.u[0].femSpace.order + except: + pass + if self.delta_x_ij is None: + self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') + argsDict = cArgumentsDict.ArgumentsDict() + argsDict["dt"] = self.timeIntegration.dt + argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi + argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi + argsDict["mesh_dof"] = self.mesh.nodeArray + argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray + argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN + argsDict["mesh_l2g"] = self.mesh.elementNodesArray + argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] + argsDict["u_trial_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi + argsDict["u_test_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi + argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace + argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace + argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] + argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals + argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians + argsDict["nElements_global"] = self.mesh.nElements_global + argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] + argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, + argsDict["isSeepageFace"] = self.coefficients.isSeepageFace + argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] + argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] + argsDict["rho"] = self.coefficients.rho + argsDict["beta"] = self.coefficients.beta + argsDict["gravity"] = self.coefficients.gravity + argsDict["alpha"] = self.coefficients.vgm_alpha_types + argsDict["n"] = self.coefficients.vgm_n_types + argsDict["thetaR"] = self.coefficients.thetaR_types + argsDict["thetaSR"] = self.coefficients.thetaSR_types + argsDict["KWs"] = self.coefficients.Ksw_types + argsDict["useMetrics"] = 0.0 + argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf + argsDict["lag_shockCapturing"] = 0 + argsDict["shockCapturingDiffusion"] = 0.0 + argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g + argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] + argsDict["elementDiameter"] = self.mesh.elementDiametersArray + argsDict["degree_polynomial"] = degree_polynomial + argsDict["u_dof"] = self.u[0].dof + argsDict["velocity"] = self.q['velocity'] + argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] + argsDict["cfl"] = self.q[('cfl',0)] + argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] + argsDict["csrRowIndeces_u_u"] = self.csrRowIndeces[(0,0)] + argsDict["csrColumnOffsets_u_u"] = self.csrColumnOffsets[(0,0)] + argsDict["globalJacobian"] = jacobian.getCSRrepresentation()[2] + argsDict["delta_x_ij"] = self.delta_x_ij + argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global + argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray + argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray + argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray + argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] + argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] + argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] + argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] + argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] + argsDict["csrColumnOffsets_eb_u_u"] = self.csrColumnOffsets_eb[(0,0)] + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + + #arnob trying to calculate flux + #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #Arnob trying to print flux + #argsDict["anb_seepage_flux"] = self.calculateResidual.anb_seepage_flux + + #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #print("Hi Seepage Flux", self.coefficients.anb_seepage_flux) + #print("Hi Seepage Flux",anb_seepage_flux) + #print("The seepage is ", anb_seepage_flux) + + + + + self.calculateJacobian(argsDict) + if self.forceStrongConditions: + for dofN in list(self.dirichletConditionsForceDOF[0].DOFBoundaryConditionsDict.keys()): + global_dofN = self.offset[0]+self.stride[0]*dofN + self.nzval[np.where(self.colind == global_dofN)] = 0.0 #column + self.nzval[self.rowptr[global_dofN]:self.rowptr[global_dofN+1]] = 0.0 #row + zeroRow=True + for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]):#row + if (self.colind[i] == global_dofN): + self.nzval[i] = 1.0 + zeroRow = False + if zeroRow: + raise RuntimeError("Jacobian has a zero row because sparse matrix has no diagonal entry at row "+repr(global_dofN)+". You probably need add diagonal mass or reaction term") + #scaling = 1.0#probably want to add some scaling to match non-dirichlet diagonals in linear system + #for cj in range(self.nc): + # for dofN in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.keys()): + # global_dofN = self.offset[cj]+self.stride[cj]*dofN + # for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]): + # if (self.colind[i] == global_dofN): + # self.nzval[i] = scaling + # else: + # self.nzval[i] = 0.0 + logEvent("Jacobian ",level=10,data=jacobian) + #mwf decide if this is reasonable for solver statistics + self.nonlinear_function_jacobian_evaluations += 1 + return jacobian + def calculateElementQuadrature(self): + """ + Calculate the physical location and weights of the quadrature rules + and the shape information at the quadrature points. + + This function should be called only when the mesh changes. + """ + #self.u[0].femSpace.elementMaps.getValues(self.elementQuadraturePoints, + # self.q['x']) + self.u[0].femSpace.elementMaps.getBasisValuesRef(self.elementQuadraturePoints) + self.u[0].femSpace.elementMaps.getBasisGradientValuesRef(self.elementQuadraturePoints) + self.u[0].femSpace.getBasisValuesRef(self.elementQuadraturePoints) + self.u[0].femSpace.getBasisGradientValuesRef(self.elementQuadraturePoints) + self.coefficients.initializeElementQuadrature(self.timeIntegration.t,self.q) + if self.stabilization != None: + self.stabilization.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) + self.stabilization.initializeTimeIntegration(self.timeIntegration) + if self.shockCapturing != None: + self.shockCapturing.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) + def calculateElementBoundaryQuadrature(self): + pass + def calculateExteriorElementBoundaryQuadrature(self): + """ + Calculate the physical location and weights of the quadrature rules + and the shape information at the quadrature points on global element boundaries. + + This function should be called only when the mesh changes. + """ + # + #get physical locations of element boundary quadrature points + # + #assume all components live on the same mesh + self.u[0].femSpace.elementMaps.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.elementMaps.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.elementMaps.getValuesGlobalExteriorTrace(self.elementBoundaryQuadraturePoints, + self.ebqe['x']) + self.fluxBoundaryConditionsObjectsDict = dict([(cj,FluxBoundaryConditions(self.mesh, + self.nElementBoundaryQuadraturePoints_elementBoundary, + self.ebqe[('x')], + getAdvectiveFluxBoundaryConditions=self.advectiveFluxBoundaryConditionsSetterDict[cj], + getDiffusiveFluxBoundaryConditions=self.diffusiveFluxBoundaryConditionsSetterDictDict[cj])) + for cj in list(self.advectiveFluxBoundaryConditionsSetterDict.keys())]) + self.coefficients.initializeGlobalExteriorElementBoundaryQuadrature(self.timeIntegration.t,self.ebqe) + #argsDict = cArgumentsDict.ArgumentsDict() + #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #print("Hi", self.coefficients.anb_seepage_flux) + + #print("The seepage is ", anb_seepage_flux) + def estimate_mt(self): + pass + def calculateSolutionAtQuadrature(self): + pass + def calculateAuxiliaryQuantitiesAfterStep(self): + pass + def postStep(self, t, firstStep=False): + with open('seepage_flux_nnnnk', "a") as f: + f.write("\n Time"+ ",\t" +"Seepage\n") + f.write(repr(t)+ ",\t" +repr(self.coefficients.anb_seepage_flux)) + + + +#argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux +#anb_seepage_flux= self.coefficients.anb_seepage_flux +#print("Hi",anb_seepage_flux) + + +#print("Hello from the python file", self.coefficients.anb_seepage_flux) diff --git a/richards_fct/richards/edit/Richards_fct.h b/richards_fct/richards/edit/Richards_fct.h new file mode 100644 index 0000000000..7eda28d4f6 --- /dev/null +++ b/richards_fct/richards/edit/Richards_fct.h @@ -0,0 +1,3174 @@ +#ifndef Richards_H +#define Richards_H +#include +#include +#include +#include "CompKernel.h" +#include "ModelFactory.h" +#include "../mprans/ArgumentsDict.h" +#include "xtensor-python/pyarray.hpp" +#define nnz nSpace + +namespace py = pybind11; +#define POWER_SMOOTHNESS_INDICATOR 2 +#define IS_BETAij_ONE 0 +#define GLOBAL_FCT 0 +namespace proteus +{ + // Power entropy // + inline double ENTROPY(const double& phi, const double& phiL, const double& phiR){ + return 1./2.*std::pow(fabs(phi),2.); + } + inline double DENTROPY(const double& phi, const double& phiL, const double& phiR){ + return fabs(phi)*(phi>=0 ? 1 : -1); + } + // Log entropy // for level set from 0 to 1 + inline double ENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ + return std::log(fabs((phi-phiL)*(phiR-phi))+1E-14); + } + inline double DENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ + return (phiL+phiR-2*phi)*((phi-phiL)*(phiR-phi)>=0 ? 1 : -1)/(fabs((phi-phiL)*(phiR-phi))+1E-14); + } +} + +namespace proteus +{ + class Richards_base + { + //The base class defining the interface + public: + virtual ~Richards_base(){} + virtual void calculateResidual(arguments_dict& args)=0; + virtual void calculateJacobian(arguments_dict& args)=0; + virtual void invert(arguments_dict& args)=0; + virtual void FCTStep(arguments_dict& args)=0; + virtual void kth_FCT_step(arguments_dict& args)=0; + virtual void calculateResidual_entropy_viscosity(arguments_dict& args)=0; + virtual void calculateMassMatrix(arguments_dict& args)=0; + }; + + template + class Richards : public Richards_base + { + public: + const int nDOF_test_X_trial_element; + CompKernelType ck; + Richards(): + nDOF_test_X_trial_element(nDOF_test_element*nDOF_trial_element), + ck() + {} + inline + void evaluateCoefficients(const int rowptr[nSpace], + const int colind[nnz], + const double rho, + const double beta, + const double gravity[nSpace], + const double alpha, + const double n_vg, + const double thetaR, + const double thetaSR, + const double KWs[nnz], + const double& u, + double& m, + double& dm, + double f[nSpace], + double df[nSpace], + double a[nnz], + double da[nnz], + double as[nnz], + double& kr, + double& dkr) + { + const int nSpace2 = nSpace * nSpace; + double psiC; + double pcBar; + double pcBar_n; + double pcBar_nM1; + double pcBar_nM2; + double onePlus_pcBar_n; + double sBar; + double sqrt_sBar; + double DsBar_DpsiC; + double thetaW; + double DthetaW_DpsiC; + double vBar; + double vBar2; + double DvBar_DpsiC; + double KWr; + double DKWr_DpsiC; + double rho2 = rho * rho; + double thetaS; + double rhom; + double drhom; + double m_vg; + double pcBarStar; + double sqrt_sBarStar; + + psiC = -u; + m_vg = 1.0 - 1.0 / n_vg; + thetaS = thetaR + thetaSR; + if (psiC > 0.0) + { + pcBar = alpha * psiC; + pcBarStar = pcBar; + if (pcBar < 1.0e-8) + pcBarStar = 1.0e-8; + pcBar_nM2 = pow(pcBarStar, n_vg - 2); + pcBar_nM1 = pcBar_nM2 * pcBar; + pcBar_n = pcBar_nM1 * pcBar; + onePlus_pcBar_n = 1.0 + pcBar_n; + + sBar = pow(onePlus_pcBar_n, -m_vg); + /* using -mn = 1-n */ + DsBar_DpsiC = alpha * (1.0 - n_vg) * (sBar/onePlus_pcBar_n)*pcBar_nM1; + + vBar = 1.0-pcBar_nM1*sBar; + vBar2 = vBar*vBar; + DvBar_DpsiC = -alpha*(n_vg-1.0)*pcBar_nM2*sBar - pcBar_nM1*DsBar_DpsiC; + + thetaW = thetaSR*sBar + thetaR; + DthetaW_DpsiC = thetaSR * DsBar_DpsiC; + + sqrt_sBar = sqrt(sBar); + sqrt_sBarStar = sqrt_sBar; + if (sqrt_sBar < 1.0e-8) + sqrt_sBarStar = 1.0e-8; + KWr= sqrt_sBar*vBar2; + DKWr_DpsiC= ((0.5/sqrt_sBarStar)*DsBar_DpsiC*vBar2 + + + 2.0*sqrt_sBar*vBar*DvBar_DpsiC); + } + else + { + thetaW = thetaS; + DthetaW_DpsiC = 0.0; + KWr = 1.0; + DKWr_DpsiC = 0.0; + } + //slight compressibility + rhom = rho*exp(beta*u); + drhom = beta*rhom; + m = rhom*thetaW; + dm = -rhom*DthetaW_DpsiC+drhom*thetaW; + for (int I=0;I thetaS || thetaW <= thetaR) + { + //cek debug + std::cout<<"rho "< 0.0) + { + isDOFBoundary = 1; + bc_u = bc_u_seepage; + } + else + { + isDOFBoundary = 0; + flux = 0.0; + } + } + /* //set DOF flag and flux correctly if seepage face */ + /* if (isSeepageFace) */ + /* { */ + /* if (flux < 0.0 || u < bc_u_seepage) */ + /* { */ + /* isDOFBoundary = 0; */ + /* flux = 0.0; */ + /* } */ + /* else */ + /* { */ + /* isDOFBoundary = 1; */ + /* bc_u = bc_u_seepage; */ + /* } */ + /* } */ + /* //Dirichlet penalty */ + /* if (isDOFBoundary) */ + /* flux += penalty*(u-bc_u); */ + } + else + flux = bc_flux; + } + + void exteriorNumericalFluxJacobian(const int rowptr[nSpace], + const int colind[nnz], + const int isDOFBoundary, + const double n[nSpace], + const double K[nnz], + const double dK[nnz], + const double grad_psi[nSpace], + const double grad_v[nSpace], + const double dK_rho_g[nSpace], + const double v, + const double penalty, + double& fluxJacobian) + { + if (isDOFBoundary) + { + fluxJacobian = 0.0; + for(int I=0;I& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + double sc_uref = args.scalar("sc_uref"); + double sc_alpha = args.scalar("sc_alpha"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& u_dof_old = args.array("u_dof_old"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m = args.array("q_m"); + xt::pyarray& q_u = args.array("q_u"); + xt::pyarray& q_dV = args.array("q_dV"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + int offset_u = args.scalar("offset_u"); + int stride_u = args.scalar("stride_u"); + xt::pyarray& globalResidual = args.array("globalResidual"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& ebqe_phi = args.array("ebqe_phi"); + double epsFact = args.scalar("epsFact"); + xt::pyarray& ebqe_u = args.array("ebqe_u"); + xt::pyarray& ebqe_flux = args.array("ebqe_flux"); + // PARAMETERS FOR EDGE BASED STABILIZATION + double cE = args.scalar("cE"); + double cK = args.scalar("cK"); + // PARAMETERS FOR LOG BASED ENTROPY FUNCTION + double uL = args.scalar("uL"); + double uR = args.scalar("uR"); + // PARAMETERS FOR EDGE VISCOSITY + int numDOFs = args.scalar("numDOFs"); + int NNZ = args.scalar("NNZ"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); + xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); + xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); + xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); + // C matrices + xt::pyarray& Cx = args.array("Cx"); + xt::pyarray& Cy = args.array("Cy"); + xt::pyarray& Cz = args.array("Cz"); + xt::pyarray& CTx = args.array("CTx"); + xt::pyarray& CTy = args.array("CTy"); + xt::pyarray& CTz = args.array("CTz"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); + int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); + // FOR FCT + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& fluxMatrix = args.array("fluxMatrix"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); + xt::pyarray& min_s_bc = args.array("min_s_bc"); + xt::pyarray& max_s_bc = args.array("max_s_bc"); + // AUX QUANTITIES OF INTEREST + xt::pyarray& quantDOFs = args.array("quantDOFs"); + xt::pyarray& sLow = args.array("sLow"); + xt::pyarray& sn = args.array("sn"); + + assert(a_rowptr.data()[nSpace] == nnz); + assert(a_rowptr.data()[nSpace] == nSpace); + //cek should this be read in? + double Ct_sge = 4.0; + + //loop over elements to compute volume integrals and load them into element and global residual + // + //eN is the element index + //eN_k is the quadrature point index for a scalar + //eN_k_nSpace is the quadrature point index for a vector + //eN_i is the element test function index + //eN_j is the element trial function index + //eN_k_j is the quadrature point index for a trial function + //eN_k_i is the quadrature point index for a trial function + for(int eN=0;eN& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); + xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); + xt::pyarray& globalJacobian = args.array("globalJacobian"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + assert(a_rowptr.data()[nSpace] == nnz); + assert(a_rowptr.data()[nSpace] == nSpace); + double Ct_sge = 4.0; + + // + //loop over elements to compute volume integrals and load them into the element Jacobians and global Jacobian + // + for(int eN=0;eN& bc_mask = args.array("bc_mask"); + int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern + int numDOFs = args.scalar("numDOFs"); //number of DOFs + double dt = args.scalar("dt"); + xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) + + xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn + xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn + xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& limited_solution = args.array("limited_solution"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets + xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices + xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 + xt::pyarray& max_s_bc = args.array("max_s_bc"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int MONOLITHIC = args.scalar("MONOLITHIC"); + register double Rpos[numDOFs], Rneg[numDOFs]; + register double FluxCorrectionMatrix[NNZ]; + register double solL[numDOFs]; + register double sdot[numDOFs]; + ////////////////////// + //arnob adding the flux correction + /////////////////////// + //xt::pyarray& antidiffusive_term_with_limiter = args.array("antidiffusive_term_with_limiter"); + + + ////////////////// + // LOOP in DOFs // + ////////////////// + int ij=0; + for (int i=0; i 0) ? 1. : 0.); + Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); + + //update ij + ij+=1; + //std::cout<<"sdoti error"<0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])) + * FluxCorrectionMatrix[ij]; + alpha_dot = fmin(1.0, beta_ij*fabs(alpha_fA)/MassMatrix.data()[ij]/fmax(1.0e-8,fabs(sdoti-sdotj))); + if (MONOLITHIC == 0) + { + ith_Limiter_times_FluxCorrectionMatrix += alpha_fA; + } + else + { + ith_Limiter_times_FluxCorrectionMatrix += alpha_fA + (LUMPED_MASS_MATRIX == 1 ? 0. : 1.)*dt*alpha_dot*MassMatrix.data()[ij]*(sdoti-sdotj); + } + //update ij + ij+=1; + } + limited_solution.data()[i] = solL[i] + 1./lumped_mass_matrix.data()[i]*ith_Limiter_times_FluxCorrectionMatrix*bc_mask[i]; + //antidiffusive_term_with_limiter.data()[i]= ith_Limiter_times_FluxCorrectionMatrix; + ////////////////////// + //arnob adding the flux correction + /////////////////////// + //xt::pyarray& antidiffusive_term_with_limiter = args.array("antidiffusive_term_with_limiter"); + + } + } + + void kth_FCT_step(arguments_dict& args) + { + int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern + int numDOFs = args.scalar("numDOFs"); //number of DOFs + int num_fct_iter = args.scalar("num_fct_iter"); + double dt = args.scalar("dt"); + xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) + xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn + xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn + xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& solLim = args.array("limited_solution"); + xt::pyarray& MC = args.array("MC"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& FluxMatrix = args.array("FluxMatrix"); + xt::pyarray& limitedFlux = args.array("limited_Flux"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets + xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices + xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 + xt::pyarray& max_s_bc = args.array("max_s_bc"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int MONOLITHIC = args.scalar("MONOLITHIC"); + register double Rpos[numDOFs], Rneg[numDOFs]; + int ij=0; + + + + + + ////////////////////////////////////////////////////// + // ********** COMPUTE LOW ORDER SOLUTION ********** // + ////////////////////////////////////////////////////// + if (num_fct_iter == 0) + { // No FCT for global bounds + for (int i=0; i 0) ? 1. : 0.); + // update ij + ij+=1; + } + // compute Q vectors + double mi = ML.data()[i]; + double solLimi = solLim.data()[i]; + double Qposi = mi*(maxi-solLimi); + // compute R vectors + Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + } + ij=0; + for (int i=0; i0 ? Rposi : Rpos[j]); + // compute limited flux + ith_Limiter_times_FluxCorrectionMatrix += Lij*Fluxij; + + // update limited flux + limitedFlux.data()[ij] = Lij*Fluxij; + + //update FluxMatrix + FluxMatrix.data()[ij] = Fluxij; + + //update ij + ij+=1; + } + + //update limited solution + double mi = ML.data()[i]; + solLim.data()[i] += 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; + //arnob edit + + + } + } + } + + // ***************************************** // + // ********** HIGH ORDER SOLUTION ********** // + // ***************************************** // + ij=0; + for (int i=0; i 0 ? 1. : 0.); + Pnegi += fij * (fij < 0 ? 1. : 0.); + //update ij + ij+=1; + } + // compute Q vectors // + double mi = ML.data()[i]; + double Qposi = mi*(maxi-solLim.data()[i]); + double Qnegi = mi*(mini-solLim.data()[i]); + // compute R vectors // + Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); + } + + // COMPUTE LIMITERS // + ij=0; + for (int i=0; i 0 ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j]); + // compute ith_limited_flux_correction + ith_limited_flux_correction += Lij*fij; + ij+=1; + } + double mi = ML.data()[i]; + solLim[i] += 1./mi*ith_limited_flux_correction; + } + } + + void calculateResidual_entropy_viscosity(arguments_dict& args) + { + xt::pyarray& globalJacobian = args.array("globalJacobian"); + double Theta = args.scalar("Theta"); + xt::pyarray& bc_mask = args.array("bc_mask"); + double dt = args.scalar("dt"); + xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + double sc_uref = args.scalar("sc_uref"); + double sc_alpha = args.scalar("sc_alpha"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& r_l2g = args.array("r_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + int degree_polynomial = args.scalar("degree_polynomial"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& u_dof_old = args.array("u_dof_old"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m = args.array("q_m"); + xt::pyarray& q_u = args.array("q_u"); + xt::pyarray& q_dV = args.array("q_dV"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + int offset_u = args.scalar("offset_u"); + int stride_u = args.scalar("stride_u"); + xt::pyarray& globalResidual = args.array("globalResidual"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& ebqe_phi = args.array("ebqe_phi"); + double epsFact = args.scalar("epsFact"); + xt::pyarray& ebqe_u = args.array("ebqe_u"); + xt::pyarray& ebqe_flux = args.array("ebqe_flux"); + // PARAMETERS FOR EDGE BASED STABILIZATION + double cE = args.scalar("cE"); + double cK = args.scalar("cK"); + // PARAMETERS FOR LOG BASED ENTROPY FUNCTION + double uL = args.scalar("uL"); + double uR = args.scalar("uR"); + // PARAMETERS FOR EDGE VISCOSITY + int numDOFs = args.scalar("numDOFs"); + int NNZ = args.scalar("NNZ"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); + xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); + xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); + xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); + // C matrices + xt::pyarray& Cx = args.array("Cx"); + xt::pyarray& Cy = args.array("Cy"); + xt::pyarray& Cz = args.array("Cz"); + xt::pyarray& CTx = args.array("CTx"); + xt::pyarray& CTy = args.array("CTy"); + xt::pyarray& CTz = args.array("CTz"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); + int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); + // FOR FCT + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& fluxMatrix = args.array("fluxMatrix"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); + xt::pyarray& min_s_bc = args.array("min_s_bc"); + xt::pyarray& max_s_bc = args.array("max_s_bc"); + // AUX QUANTITIES OF INTEREST + xt::pyarray& quantDOFs = args.array("quantDOFs"); + xt::pyarray& sLow = args.array("sLow"); + xt::pyarray& sn = args.array("sn"); + register double Rpos[numDOFs], Rneg[numDOFs]; + //register double FluxCorrectionMatrix[NNZ]; + // NOTE: This function follows a different (but equivalent) implementation of the smoothness based indicator than NCLS.h + // Allocate space for the transport matrices + // This is used for first order KUZMIN'S METHOD + register double TransportMatrix[NNZ],TransportMatrixConsistent[NNZ]; + register double TransportMatrixn[NNZ],TransportMatrixConsistentn[NNZ]; + std::valarray u_free_dof(numDOFs); + std::valarray u_free_dof_old(numDOFs); + std::valarray ML2(numDOFs); + for(int eN=0;eN= 0 && isFluxBoundary_u[ebNE_kb] != 1 ) //outflow. This is handled via the transport matrices. Then flux_ext=0 and dflux_ext!=0 */ + /* { */ + /* dflux_ext = flow; */ + /* flux_ext = 0; */ + /* // save external u */ + /* ebqe_u[ebNE_kb] = u_ext; */ + /* } */ + /* else // inflow. This is handled via the boundary integral. Then flux_ext!=0 and dflux_ext=0 */ + /* { */ + /* dflux_ext = 0; */ + /* // save external u */ + /* ebqe_u[ebNE_kb] = isDOFBoundary_u[ebNE_kb]*ebqe_bc_u_ext[ebNE_kb]+(1-isDOFBoundary_u[ebNE_kb])*u_ext; */ + /* if (isDOFBoundary_u[ebNE_kb] == 1) */ + /* flux_ext = ebqe_bc_u_ext[ebNE_kb]*flow; */ + /* else if (isFluxBoundary_u[ebNE_kb] == 1) */ + /* flux_ext = ebqe_bc_flux_u_ext[ebNE_kb]; */ + /* else */ + /* { */ + /* std::cout<<"warning: VOF open boundary with no external trace, setting to zero for inflow"<= 0.) + { + alpha_numerator_pos += alpha_num; + alpha_denominator_pos += alpha_num; + } + else + { + alpha_numerator_neg += alpha_num; + alpha_denominator_neg += fabs(alpha_num); + } + //update ij + ij+=1; + } + // scale g vector by lumped mass matrix + if (fabs(ML.data()[i] - ML2[i]) > 1.0e-16) + std::cout<<"ML "< 0.0) + // assert( (xi[I] - xj[I]) == delta_x_ij[offset*3+I]); + //gi_times_x += gi[I]*(xi[I]-xj[I]); + gi_times_x += gi[I]*delta_x_ij.data()[offset*3+I]; + } + // compute the positive and negative part of gi*(xi-xj) + SumPos += gi_times_x > 0 ? gi_times_x : 0; + SumNeg += gi_times_x < 0 ? gi_times_x : 0; + } + double sigmaPosi = fmin(1.,(fabs(SumNeg)+1E-15)/(SumPos+1E-15)); + double sigmaNegi = fmin(1.,(SumPos+1E-15)/(fabs(SumNeg)+1E-15)); + double alpha_numi = fabs(sigmaPosi*alpha_numerator_pos + sigmaNegi*alpha_numerator_neg); + double alpha_deni = sigmaPosi*alpha_denominator_pos + sigmaNegi*alpha_denominator_neg; + if (IS_BETAij_ONE == 1) + { + alpha_numi = fabs(alpha_numerator_pos + alpha_numerator_neg); + alpha_deni = alpha_denominator_pos + alpha_denominator_neg; + } + double alphai = alpha_numi/(alpha_deni+1E-15); + quantDOFs.data()[i] = alphai; + + if (POWER_SMOOTHNESS_INDICATOR==0) + psi[i] = 1.0; + else + psi[i] = std::pow(alphai,POWER_SMOOTHNESS_INDICATOR); //NOTE: they use alpha^2 in the paper + } + ///////////////////////////////////////////// + // ** LOOP IN DOFs FOR EDGE BASED TERMS ** // + ///////////////////////////////////////////// + ij=0; + for (int i=0; i Dissipation matrices as well. + double soli = u_free_dof[i]; // solution at time tn for the ith DOF + double solni = u_free_dof_old[i]; // solution at time tn for the ith DOF + for (int I=0;I& bc_mask = args.array("bc_mask"); + int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern + int numDOFs = args.scalar("numDOFs"); //number of DOFs + double dt = args.scalar("dt"); + xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) + + xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn + xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn + xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& limited_solution = args.array("limited_solution"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets + xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices + xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 + xt::pyarray& max_s_bc = args.array("max_s_bc"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int MONOLITHIC = args.scalar("MONOLITHIC"); + register double Rpos[numDOFs], Rneg[numDOFs]; + register double FluxCorrectionMatrix[NNZ]; + register double solL[numDOFs]; + register double sdot[numDOFs]; + ////////////////////// + //arnob adding the flux correction + /////////////////////// + //xt::pyarray& antidiffusive_term_with_limiter = args.array("antidiffusive_term_with_limiter"); + + + ////////////////// + // LOOP in DOFs // + ////////////////// + int ij=0; + for (int i=0; i 0) ? 1. : 0.); + Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); + + //update ij + ij+=1; + //std::cout<<"sdoti error"<0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])) + * FluxCorrectionMatrix[ij]; + alpha_dot = fmin(1.0, beta_ij*fabs(alpha_fA)/MassMatrix.data()[ij]/fmax(1.0e-8,fabs(sdoti-sdotj))); + if (MONOLITHIC == 0) + { + ith_Limiter_times_FluxCorrectionMatrix += alpha_fA; + } + else + { + ith_Limiter_times_FluxCorrectionMatrix += alpha_fA + (LUMPED_MASS_MATRIX == 1 ? 0. : 1.)*dt*alpha_dot*MassMatrix.data()[ij]*(sdoti-sdotj); + } + //update ij + ij+=1; + } + limited_solution.data()[i] = solL[i] + 1./lumped_mass_matrix.data()[i]*ith_Limiter_times_FluxCorrectionMatrix*bc_mask[i]; + //antidiffusive_term_with_limiter.data()[i]= ith_Limiter_times_FluxCorrectionMatrix; + ////////////////////// + //arnob adding the flux correction + /////////////////////// + //xt::pyarray& antidiffusive_term_with_limiter = args.array("antidiffusive_term_with_limiter"); + + //} + + + globalResidual.data()[i] = (mi*(m - mn)/dt - ith_flux_term)*bc_mask.data()[i]; ;//+ antidiffusive_term_with_limiter.data()[i])*bc_mask.data()[i];//cek should introduce mn,mnp1 or somethign clearer + globalJacobian.data()[ii] += bc_mask.data()[i]*(mi*dm/dt + J_ii) + (1.0-bc_mask.data()[i]); + + //if (GLOBAL_FCT==1) + //{ + //limited_solution.data()[i] = solL[i] + 1./lumped_mass_matrix.data()[i]*ith_Limiter_times_FluxCorrectionMatrix*bc_mask[i]; + //antidiffusive_term_with_limiter.data()[i]= ith_Limiter_times_FluxCorrectionMatrix + //globalResidual.data()[i] = (mi*(m - mn)/dt - ith_flux_term)*bc_mask.data()[i]; + //globalResidual.data()[i] = (mi*(m - mn)/dt - ith_flux_term + ith_Limiter_times_FluxCorrectionMatrix)*bc_mask.data()[i]; + + //+ith_Limiter_times_FluxCorrectionMatrix; + //} + //else + //{ + //globalResidual.data()[i] = (mi*(m - mn)/dt - ith_flux_term)*bc_mask.data()[i]; + } + + if (false) + { + //cek debug + //std::cout<<"dt*divergence "< mMax) + { + std::cout<<"mass out of bounds "< 0) ? 1. : 0.); + // Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); + // ij+=1; + // } + // double mi = ML[i]; + // double solni = u_dof_old[i]; + // double Qposi = mi*(maxi-solni); + // double Qnegi = mi*(mini-solni); + + //std::cout << Qposi << std::endl; + // Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + // Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); + + //if (Rpos[i] < 0) + //{ + // std::cout << mi << "\t" << maxi << "\t" << solni << std::endl; + // std::cout << Qposi << "\t" << Pposi << std::endl; + // std::cout << Rpos[i] << std::endl; + //abort(); + //} + //} + + //ij=0; + //for (int i=0; i 1.0 || Rposi < 0.0) + //std::cout << "Rposi: " << Rposi << std::endl; + //if (Rnegi > 1.0 || Rnegi < 0.0) + //std::cout << "Rnegi: " << Rnegi << std::endl; + + // LOOP OVER THE SPARSITY PATTERN (j-LOOP)// + // for (int offset=csrRowIndeces_DofLoops.data()[i]; + // offset0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])); + // //Lij=0.0; + // ith_Limiter_times_FluxCorrectionMatrix += Lij*FluxCorrectionMatrix[ij]; + // //update ij + // ij+=1; + // } + // double mi = ML[i]; + // double solni = u_dof_old[i]; + // globalResidual[i] = solni + 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; + //} + + } + + void invert(arguments_dict& args) + { + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + xt::pyarray& globalResidual = args.array("globalResidual"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + int numDOFs = args.scalar("numDOFs"); + for (int i=0; i mMax) + { + std::cout<<"mass out of bounds "<("dt"); + xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + //element boundary + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + //physics + int nElements_global = args.scalar("nElements_global"); + //new + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + //end new + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& r_l2g = args.array("r_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + int degree_polynomial = args.scalar("degree_polynomial"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); + xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); + xt::pyarray& globalJacobian = args.array("globalJacobian"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + //std::cout<<"ndjaco address "<(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + else if (nSpaceIn == 2) + return proteus::chooseAndAllocateDiscretization2D(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + else + { + assert(nSpaceIn == 3); + return proteus::chooseAndAllocateDiscretization(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + } + } +};//proteus +#endif \ No newline at end of file diff --git a/richards_fct/richards/edit/Richards_n.py b/richards_fct/richards/edit/Richards_n.py new file mode 100755 index 0000000000..450ab93293 --- /dev/null +++ b/richards_fct/richards/edit/Richards_n.py @@ -0,0 +1,1840 @@ +from __future__ import division +from builtins import range +from past.utils import old_div +import proteus +from .cRichards import * +import numpy as np +from proteus.Transport import OneLevelTransport +from proteus.Transport import TC_base, NonlinearEquation, logEvent, memory +from proteus.Transport import FluxBoundaryConditions, Comm, cfemIntegrals +from proteus.Transport import DOFBoundaryConditions, Quadrature +from proteus.mprans import cArgumentsDict +from proteus.LinearAlgebraTools import SparseMat +from proteus import TimeIntegration +from proteus.NonlinearSolvers import ExplicitLumpedMassMatrixForRichards + +class ThetaScheme(TimeIntegration.BackwardEuler): + def __init__(self,transport,integrateInterpolationPoints=False): + self.transport=transport + TimeIntegration.BackwardEuler.__init__(self,transport, integrateInterpolationPoints) + def updateTimeHistory(self,resetFromDOF=False): + TimeIntegration.BackwardEuler.updateTimeHistory(self,resetFromDOF) + self.transport.u_dof_old[:] = self.u +class RKEV(TimeIntegration.SSP): + from proteus import TimeIntegration + """ + Wrapper for SSPRK time integration using EV + + ... more to come ... + """ + + def __init__(self, transport, timeOrder=1, runCFL=0.1, integrateInterpolationPoints=False): + TimeIntegration.SSP.__init__(self, transport, integrateInterpolationPoints=integrateInterpolationPoints) + self.runCFL = runCFL + self.dtLast = None + self.isAdaptive = True + # About the cfl + assert transport.coefficients.STABILIZATION_TYPE > 0, "SSP method just works for edge based EV methods; i.e., STABILIZATION_TYPE>0" + assert hasattr(transport, 'edge_based_cfl'), "No edge based cfl defined" + self.cfl = transport.edge_based_cfl + # Stuff particular for SSP + self.timeOrder = timeOrder # order of approximation + self.nStages = timeOrder # number of stages total + self.lstage = 0 # last stage completed + # storage vectors + self.u_dof_last = {} + # per component stage values, list with array at each stage + self.u_dof_stage = {} + for ci in range(self.nc): + if ('m', ci) in transport.q: + self.u_dof_last[ci] = transport.u[ci].dof.copy() + self.u_dof_stage[ci] = [] + for k in range(self.nStages + 1): + self.u_dof_stage[ci].append(transport.u[ci].dof.copy()) + #print() + + + # def set_dt(self, DTSET): + # self.dt = DTSET # don't update t + def choose_dt(self): + comm = Comm.get() + maxCFL = 1.0e-6 + maxCFL = max(maxCFL, comm.globalMax(self.cfl.max())) + self.dt = old_div(self.runCFL, maxCFL) + if self.dtLast is None: + self.dtLast = self.dt + self.t = self.tLast + self.dt + self.substeps = [self.t for i in range(self.nStages)] # Manuel is ignoring different time step levels for now + #print("Hi, This is Arnob") + + + def initialize_dt(self, t0, tOut, q): + """ + Modify self.dt + """ + self.tLast = t0 + self.choose_dt() + self.t = t0 + self.dt + + def setCoefficients(self): + """ + beta are all 1's here + mwf not used right now + """ + self.alpha = np.zeros((self.nStages, self.nStages), 'd') + self.dcoefs = np.zeros((self.nStages), 'd') + + def updateStage(self): + """ + Need to switch to use coefficients + """ + self.lstage += 1 + assert self.timeOrder in [1, 2, 3] + assert self.lstage > 0 and self.lstage <= self.timeOrder + if self.timeOrder == 3: + if self.lstage == 1: + logEvent("First stage of SSP33 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + # update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] + elif self.lstage == 2: + logEvent("Second stage of SSP33 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + self.u_dof_stage[ci][self.lstage] *= old_div(1., 4.) + self.u_dof_stage[ci][self.lstage] += 3. / 4. * self.u_dof_last[ci] + # Update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] + elif self.lstage == 3: + logEvent("Third stage of SSP33 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + self.u_dof_stage[ci][self.lstage] *= old_div(2.0, 3.0) + self.u_dof_stage[ci][self.lstage] += 1.0 / 3.0 * self.u_dof_last[ci] + # update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_last[ci] + # update solution to u[0].dof + self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] + elif self.timeOrder == 2: + if self.lstage == 1: + logEvent("First stage of SSP22 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + # Update u_dof_old + self.transport.u_dof_old[:] = self.transport.u[ci].dof + elif self.lstage == 2: + logEvent("Second stage of SSP22 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + self.u_dof_stage[ci][self.lstage][:] *= old_div(1., 2.) + self.u_dof_stage[ci][self.lstage][:] += 1. / 2. * self.u_dof_last[ci] + # update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_last[ci] + # update solution to u[0].dof + self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] + else: + assert self.timeOrder == 1 + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof[:] + self.transport.u_dof_old[:] = self.transport.u[ci].dof + #self.print("Hi, Arnob") + + def initializeTimeHistory(self, resetFromDOF=True): + """ + Push necessary information into time history arrays + """ + for ci in range(self.nc): + self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] + for k in range(self.nStages): + self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] + + def updateTimeHistory(self, resetFromDOF=False): + """ + assumes successful step has been taken + """ + + self.t = self.tLast + self.dt + for ci in range(self.nc): + self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] + for k in range(self.nStages): + self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] + self.lstage = 0 + self.dtLast = self.dt + self.tLast = self.t + + def generateSubsteps(self, tList): + """ + create list of substeps over time values given in tList. These correspond to stages + """ + self.substeps = [] + tLast = self.tLast + for t in tList: + dttmp = t - tLast + self.substeps.extend([tLast + dttmp for i in range(self.nStages)]) + tLast = t + + def resetOrder(self, order): + """ + initialize data structures for stage updges + """ + self.timeOrder = order # order of approximation + self.nStages = order # number of stages total + self.lstage = 0 # last stage completed + # storage vectors + # per component stage values, list with array at each stage + self.u_dof_stage = {} + for ci in range(self.nc): + if ('m', ci) in self.transport.q: + self.u_dof_stage[ci] = [] + for k in range(self.nStages + 1): + self.u_dof_stage[ci].append(self.transport.u[ci].dof.copy()) + self.substeps = [self.t for i in range(self.nStages)] + + def setFromOptions(self, nOptions): + """ + allow classes to set various numerical parameters + """ + if 'runCFL' in dir(nOptions): + self.runCFL = nOptions.runCFL + flags = ['timeOrder'] + for flag in flags: + if flag in dir(nOptions): + val = getattr(nOptions, flag) + setattr(self, flag, val) + if flag == 'timeOrder': + self.resetOrder(self.timeOrder) + + + +class Coefficients(proteus.TransportCoefficients.TC_base): + """ + version of Re where element material type id's used in evals + """ + from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2 + from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchten_sd_het + def __init__(self, + nd, + Ksw_types, + vgm_n_types, + vgm_alpha_types, + thetaR_types, + thetaSR_types, + gravity, + density, + beta, + diagonal_conductivity=True, + getSeepageFace=None, + # FOR EDGE BASED EV + STABILIZATION_TYPE=0, + ENTROPY_TYPE=2, # logarithmic + LUMPED_MASS_MATRIX=False, + MONOLITHIC=True, + FCT=True, + num_fct_iter=1, + # FOR ENTROPY VISCOSITY + cE=1.0, + uL=0.0, + uR=1.0, + # FOR ARTIFICIAL COMPRESSION + cK=1.0, + # OUTPUT quantDOFs + outputQuantDOFs=False, ): + self.anb_seepage_flux= 0.00 + #self.anb_seepage_flux_n =0.0 + variableNames=['pressure_head'] + nc=1 + mass={0:{0:'nonlinear'}} + advection={0:{0:'nonlinear'}} + diffusion={0:{0:{0:'nonlinear'}}} + potential={0:{0:'u'}} + reaction={0:{0:'linear'}} + hamiltonian={} + self.getSeepageFace=getSeepageFace + self.gravity=gravity + self.rho = density + self.beta=beta + self.vgm_n_types = vgm_n_types + self.vgm_alpha_types = vgm_alpha_types + self.thetaR_types = thetaR_types + self.thetaSR_types = thetaSR_types + self.elementMaterialTypes = None + self.exteriorElementBoundaryTypes = None + self.materialTypes_q = None + self.materialTypes_ebq = None + self.materialTypes_ebqe = None + self.nd = nd + self.nMaterialTypes = len(thetaR_types) + self.q = {}; self.ebqe = {}; self.ebq = {}; self.ebq_global={} + #try to allow some flexibility in input of permeability/conductivity tensor + self.diagonal_conductivity = diagonal_conductivity + self.Ksw_types_in = Ksw_types + if self.diagonal_conductivity: + sparseDiffusionTensors = {(0,0):(np.arange(self.nd+1,dtype='i'), + np.arange(self.nd,dtype='i'))} + + assert len(Ksw_types.shape) in [1,2], "if diagonal conductivity true then Ksw_types scalar or vector of diagonal entries" + #allow scalar input Ks + if len(Ksw_types.shape)==1: + self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd),'d') + for I in range(self.nd): + self.Ksw_types[:,I] = Ksw_types + else: + self.Ksw_types = Ksw_types + else: #full + sparseDiffusionTensors = {(0,0):(np.arange(self.nd**2+1,step=self.nd,dtype='i'), + np.array([list(range(self.nd)) for row in range(self.nd)],dtype='i'))} + assert len(Ksw_types.shape) in [1,2], "if full tensor conductivity true then Ksw_types scalar or 'flattened' row-major representation of entries" + if len(Ksw_types.shape)==1: + self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd**2),'d') + for I in range(self.nd): + self.Ksw_types[:,I*self.nd+I] = Ksw_types + else: + assert Ksw_types.shape[1] == self.nd**2 + self.Ksw_types = Ksw_types + # EDGE BASED (AND ENTROPY) VISCOSITY + self.LUMPED_MASS_MATRIX = LUMPED_MASS_MATRIX + self.MONOLITHIC = MONOLITHIC + self.STABILIZATION_TYPE = STABILIZATION_TYPE + self.ENTROPY_TYPE = ENTROPY_TYPE + self.FCT = FCT + self.num_fct_iter=num_fct_iter + self.uL = uL + self.uR = uR + self.cK = cK + self.forceStrongConditions = True + self.cE = cE + self.outputQuantDOFs = outputQuantDOFs + TC_base.__init__(self, + nc, + mass, + advection, + diffusion, + potential, + reaction, + hamiltonian, + variableNames, + sparseDiffusionTensors = sparseDiffusionTensors, + useSparseDiffusion = True) + + def initializeMesh(self,mesh): + from proteus.SubsurfaceTransportCoefficients import BlockHeterogeneousCoefficients + self.elementMaterialTypes,self.exteriorElementBoundaryTypes,self.elementBoundaryTypes = BlockHeterogeneousCoefficients(mesh).initializeMaterialTypes() + #want element boundary material types for evaluating heterogeneity + #not boundary conditions + self.isSeepageFace = np.zeros((mesh.nExteriorElementBoundaries_global),'i') + if self.getSeepageFace != None: + for ebNE in range(mesh.nExteriorElementBoundaries_global): + #mwf missing ebNE-->ebN? + ebN = mesh.exteriorElementBoundariesArray[ebNE] + #print "eb flag",mesh.elementBoundaryMaterialTypes[ebN] + #print("Hi, Arnob") + #print self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) + self.isSeepageFace[ebNE] = self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) + #print (self.isSeepageFace) + def initializeElementQuadrature(self,t,cq): + self.materialTypes_q = self.elementMaterialTypes + self.q_shape = cq[('u',0)].shape + #self.anb_seepage_flux= anb_seepage_flux + #print("The seepage is ", anb_seepage_flux) +# cq['Ks'] = np.zeros(self.q_shape,'d') +# for k in range(self.q_shape[1]): +# cq['Ks'][:,k] = self.Ksw_types[self.elementMaterialTypes,0] + self.q[('vol_frac',0)] = np.zeros(self.q_shape,'d') + def initializeElementBoundaryQuadrature(self,t,cebq,cebq_global): + self.materialTypes_ebq = np.zeros(cebq[('u',0)].shape[0:2],'i') + self.ebq_shape = cebq[('u',0)].shape + for ebN_local in range(self.ebq_shape[1]): + self.materialTypes_ebq[:,ebN_local] = self.elementMaterialTypes + self.ebq[('vol_frac',0)] = np.zeros(self.ebq_shape,'d') + + def initializeGlobalExteriorElementBoundaryQuadrature(self,t,cebqe): + self.materialTypes_ebqe = self.exteriorElementBoundaryTypes + self.ebqe_shape = cebqe[('u',0)].shape + self.ebqe[('vol_frac',0)] = np.zeros(self.ebqe_shape,'d') + # + + + def evaluate(self,t,c): + if c[('u',0)].shape == self.q_shape: + materialTypes = self.materialTypes_q + vol_frac = self.q[('vol_frac',0)] + elif c[('u',0)].shape == self.ebqe_shape: + materialTypes = self.materialTypes_ebqe + vol_frac = self.ebqe[('vol_frac',0)] + elif c[('u',0)].shape == self.ebq_shape: + materialTypes = self.materialTypes_ebq + vol_frac = self.ebq[('vol_frac',0)] + else: + assert False, "no materialType found to match c[('u',0)].shape= %s " % c[('u',0)].shape + self.conservativeHeadRichardsMualemVanGenuchten_sd_het(self.sdInfo[(0,0)][0], + self.sdInfo[(0,0)][1], + materialTypes, + self.rho, + self.beta, + self.gravity, + self.vgm_alpha_types, + self.vgm_n_types, + self.thetaR_types, + self.thetaSR_types, + self.Ksw_types, + c[('u',0)], + c[('m',0)], + c[('dm',0,0)], + c[('f',0)], + c[('df',0,0)], + c[('a',0,0)], + c[('da',0,0,0)], + vol_frac) + # print "Picard---------------------------------------------------------------" + # c[('df',0,0)][:] = 0.0 + # c[('da',0,0,0)][:] = 0.0 +# self.conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2(materialTypes, +# self.rho, +# self.beta, +# self.gravity, +# self.vgm_alpha_types, +# self.vgm_n_types, +# self.thetaR_types, +# self.thetaSR_types, +# self.Ksw_types, +# c[('u',0)], +# c[('m',0)], +# c[('dm',0,0)], +# c[('f',0)], +# c[('df',0,0)], +# c[('a',0,0)], +# c[('da',0,0,0)]) + #mwf debug + if (np.isnan(c[('da',0,0,0)]).any() or + np.isnan(c[('a',0,0)]).any() or + np.isnan(c[('df',0,0)]).any() or + np.isnan(c[('f',0)]).any() or + np.isnan(c[('u',0)]).any() or + np.isnan(c[('m',0)]).any() or + np.isnan(c[('dm',0,0)]).any()): + import pdb + pdb.set_trace() + + def postStep(self, t, firstStep=False): + #anb_seepage_flux_n[:]= self.anb_seepage_flux + with open('seepage_flux_nn', "a") as f: + f.write("\n Time"+ ",\t" +"Seepage\n") + f.write(repr(t)+ ",\t" +repr(self.anb_seepage_flux)) + + + +class LevelModel(proteus.Transport.OneLevelTransport): + nCalls=0 + def __init__(self, + uDict, + phiDict, + testSpaceDict, + matType, + dofBoundaryConditionsDict, + dofBoundaryConditionsSetterDict, + coefficients, + elementQuadrature, + elementBoundaryQuadrature, + fluxBoundaryConditionsDict=None, + advectiveFluxBoundaryConditionsSetterDict=None, + diffusiveFluxBoundaryConditionsSetterDictDict=None, + stressTraceBoundaryConditionsSetterDict=None, + stabilization=None, + shockCapturing=None, + conservativeFluxDict=None, + numericalFluxType=None, + TimeIntegrationClass=None, + massLumping=False, + reactionLumping=False, + options=None, + name='defaultName', + reuse_trial_and_test_quadrature=True, + sd = True, + movingDomain=False, + bdyNullSpace=False): + self.bdyNullSpace=bdyNullSpace + # + #set the objects describing the method and boundary conditions + # + self.movingDomain=movingDomain + self.tLast_mesh=None + # + self.name=name + self.sd=sd + self.Hess=False + self.lowmem=True + self.timeTerm=True#allow turning off the time derivative + #self.lowmem=False + self.testIsTrial=True + self.phiTrialIsTrial=True + self.u = uDict + self.ua = {}#analytical solutions + self.phi = phiDict + self.dphi={} + self.matType = matType + #mwf try to reuse test and trial information across components if spaces are the same + self.reuse_test_trial_quadrature = reuse_trial_and_test_quadrature#True#False + if self.reuse_test_trial_quadrature: + for ci in range(1,coefficients.nc): + assert self.u[ci].femSpace.__class__.__name__ == self.u[0].femSpace.__class__.__name__, "to reuse_test_trial_quad all femSpaces must be the same!" + self.u_dof_old = None + ## Simplicial Mesh + self.mesh = self.u[0].femSpace.mesh #assume the same mesh for all components for now + self.testSpace = testSpaceDict + self.dirichletConditions = dofBoundaryConditionsDict + self.dirichletNodeSetList=None #explicit Dirichlet conditions for now, no Dirichlet BC constraints + self.coefficients = coefficients + self.coefficients.initializeMesh(self.mesh) + self.nc = self.coefficients.nc + self.stabilization = stabilization + self.shockCapturing = shockCapturing + self.conservativeFlux = conservativeFluxDict #no velocity post-processing for now + self.fluxBoundaryConditions=fluxBoundaryConditionsDict + self.advectiveFluxBoundaryConditionsSetterDict=advectiveFluxBoundaryConditionsSetterDict + self.diffusiveFluxBoundaryConditionsSetterDictDict = diffusiveFluxBoundaryConditionsSetterDictDict + #determine whether the stabilization term is nonlinear + self.stabilizationIsNonlinear = False + #cek come back + if self.stabilization != None: + for ci in range(self.nc): + if ci in coefficients.mass: + for flag in list(coefficients.mass[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.advection: + for flag in list(coefficients.advection[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.diffusion: + for diffusionDict in list(coefficients.diffusion[ci].values()): + for flag in list(diffusionDict.values()): + if flag != 'constant': + self.stabilizationIsNonlinear=True + if ci in coefficients.potential: + for flag in list(coefficients.potential[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.reaction: + for flag in list(coefficients.reaction[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.hamiltonian: + for flag in list(coefficients.hamiltonian[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + #determine if we need element boundary storage + self.elementBoundaryIntegrals = {} + for ci in range(self.nc): + self.elementBoundaryIntegrals[ci] = ((self.conservativeFlux != None) or + (numericalFluxType != None) or + (self.fluxBoundaryConditions[ci] == 'outFlow') or + (self.fluxBoundaryConditions[ci] == 'mixedFlow') or + (self.fluxBoundaryConditions[ci] == 'setFlow')) + # + #calculate some dimensions + # + self.nSpace_global = self.u[0].femSpace.nSpace_global #assume same space dim for all variables + self.nDOF_trial_element = [u_j.femSpace.max_nDOF_element for u_j in list(self.u.values())] + self.nDOF_phi_trial_element = [phi_k.femSpace.max_nDOF_element for phi_k in list(self.phi.values())] + self.n_phi_ip_element = [phi_k.femSpace.referenceFiniteElement.interpolationConditions.nQuadraturePoints for phi_k in list(self.phi.values())] + self.nDOF_test_element = [femSpace.max_nDOF_element for femSpace in list(self.testSpace.values())] + self.nFreeDOF_global = [dc.nFreeDOF_global for dc in list(self.dirichletConditions.values())] + self.nVDOF_element = sum(self.nDOF_trial_element) + self.nFreeVDOF_global = sum(self.nFreeDOF_global) + # + NonlinearEquation.__init__(self,self.nFreeVDOF_global) + # + #build the quadrature point dictionaries from the input (this + #is just for convenience so that the input doesn't have to be + #complete) + # + elementQuadratureDict={} + elemQuadIsDict = isinstance(elementQuadrature,dict) + if elemQuadIsDict: #set terms manually + for I in self.coefficients.elementIntegralKeys: + if I in elementQuadrature: + elementQuadratureDict[I] = elementQuadrature[I] + + else: + elementQuadratureDict[I] = elementQuadrature['default'] + else: + for I in self.coefficients.elementIntegralKeys: + elementQuadratureDict[I] = elementQuadrature + if self.stabilization != None: + for I in self.coefficients.elementIntegralKeys: + if elemQuadIsDict: + if I in elementQuadrature: + elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature[I] + else: + elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature['default'] + else: + elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature + if self.shockCapturing != None: + for ci in self.shockCapturing.components: + if elemQuadIsDict: + if ('numDiff',ci,ci) in elementQuadrature: + elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature[('numDiff',ci,ci)] + #print("Hi, Arnob1") + #print(anb_seepage_flux) + else: + elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature['default'] + #print("Hi, Arnob2") + #print(anb_seepage_flux) + else: + elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature + print("Hi, Arnob3") + #print(anb_seepage_flux) + if massLumping: + for ci in list(self.coefficients.mass.keys()): + elementQuadratureDict[('m',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + print("Hi, Arnob4") + #print(anb_seepage_flux) + for I in self.coefficients.elementIntegralKeys: + elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + print("Hi, Arnob5") + #print(anb_seepage_flux) + if reactionLumping: + for ci in list(self.coefficients.mass.keys()): + elementQuadratureDict[('r',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + print("Hi, Arnob6") + #print(anb_seepage_flux) + for I in self.coefficients.elementIntegralKeys: + elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + print("Hi, Arnob7") + #print(anb_seepage_flux) + elementBoundaryQuadratureDict={} + if isinstance(elementBoundaryQuadrature,dict): #set terms manually + for I in self.coefficients.elementBoundaryIntegralKeys: + if I in elementBoundaryQuadrature: + elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature[I] + print("Hi, Arnob8") + #print(anb_seepage_flux) + else: + elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature['default'] + #print("Hi, Arnob9") + #print(anb_seepage_flux) + else: + for I in self.coefficients.elementBoundaryIntegralKeys: + elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature + print("Hi, Arnob10") + #print(anb_seepage_flux) + # + # find the union of all element quadrature points and + # build a quadrature rule for each integral that has a + # weight at each point in the union + #mwf include tag telling me which indices are which quadrature rule? + (self.elementQuadraturePoints,self.elementQuadratureWeights, + self.elementQuadratureRuleIndeces) = Quadrature.buildUnion(elementQuadratureDict) + self.nQuadraturePoints_element = self.elementQuadraturePoints.shape[0] + self.nQuadraturePoints_global = self.nQuadraturePoints_element*self.mesh.nElements_global + # + #Repeat the same thing for the element boundary quadrature + # + (self.elementBoundaryQuadraturePoints, + self.elementBoundaryQuadratureWeights, + self.elementBoundaryQuadratureRuleIndeces) = Quadrature.buildUnion(elementBoundaryQuadratureDict) + self.nElementBoundaryQuadraturePoints_elementBoundary = self.elementBoundaryQuadraturePoints.shape[0] + self.nElementBoundaryQuadraturePoints_global = (self.mesh.nElements_global* + self.mesh.nElementBoundaries_element* + self.nElementBoundaryQuadraturePoints_elementBoundary) +# if isinstance(self.u[0].femSpace,C0_AffineLinearOnSimplexWithNodalBasis): +# print self.nQuadraturePoints_element +# if self.nSpace_global == 3: +# assert(self.nQuadraturePoints_element == 5) +# elif self.nSpace_global == 2: +# assert(self.nQuadraturePoints_element == 6) +# elif self.nSpace_global == 1: +# assert(self.nQuadraturePoints_element == 3) +# +# print self.nElementBoundaryQuadraturePoints_elementBoundary +# if self.nSpace_global == 3: +# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) +# elif self.nSpace_global == 2: +# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) +# elif self.nSpace_global == 1: +# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 1) + + # + #storage dictionaries + self.scalars_element = set() + # + #simplified allocations for test==trial and also check if space is mixed or not + # + self.q={} + self.ebq={} + self.ebq_global={} + self.ebqe={} + self.phi_ip={} + self.edge_based_cfl = np.zeros(self.u[0].dof.shape)+100 + #mesh + #self.q['x'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,3),'d') + self.q[('dV_u', 0)] = (old_div(1.0, self.mesh.nElements_global)) * np.ones((self.mesh.nElements_global, self.nQuadraturePoints_element), 'd') + self.ebqe['x'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,3),'d') + self.q[('u',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') + self.q[('grad(u)',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') + self.q['velocity'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') + self.q[('m',0)] = self.q[('u',0)].copy() + self.q[('mt',0)] = self.q[('u',0)].copy() + self.q[('m_last',0)] = self.q[('u',0)].copy() + self.q[('m_tmp',0)] = self.q[('u',0)].copy() + self.q[('cfl',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') + self.q[('numDiff',0,0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') + self.ebqe[('u',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.ebqe[('grad(u)',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') + self.ebqe['velocity'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') + self.ebqe[('advectiveFlux_bc_flag',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'i') + self.ebqe[('advectiveFlux_bc',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.ebqe[('advectiveFlux',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.ebqe[('penalty')] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.points_elementBoundaryQuadrature= set() + self.scalars_elementBoundaryQuadrature= set([('u',ci) for ci in range(self.nc)]) + self.vectors_elementBoundaryQuadrature= set() + self.tensors_elementBoundaryQuadrature= set() + self.inflowBoundaryBC = {} + self.inflowBoundaryBC_values = {} + self.inflowFlux = {} + for cj in range(self.nc): + self.inflowBoundaryBC[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,),'i') + self.inflowBoundaryBC_values[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nDOF_trial_element[cj]),'d') + self.inflowFlux[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.internalNodes = set(range(self.mesh.nNodes_global)) + #identify the internal nodes this is ought to be in mesh + ##\todo move this to mesh + for ebNE in range(self.mesh.nExteriorElementBoundaries_global): + ebN = self.mesh.exteriorElementBoundariesArray[ebNE] + eN_global = self.mesh.elementBoundaryElementsArray[ebN,0] + ebN_element = self.mesh.elementBoundaryLocalElementBoundariesArray[ebN,0] + for i in range(self.mesh.nNodes_element): + if i != ebN_element: + I = self.mesh.elementNodesArray[eN_global,i] + self.internalNodes -= set([I]) + self.nNodes_internal = len(self.internalNodes) + self.internalNodesArray=np.zeros((self.nNodes_internal,),'i') + for nI,n in enumerate(self.internalNodes): + self.internalNodesArray[nI]=n + # + del self.internalNodes + self.internalNodes = None + logEvent("Updating local to global mappings",2) + self.updateLocal2Global() + logEvent("Building time integration object",2) + logEvent(memory("inflowBC, internalNodes,updateLocal2Global","OneLevelTransport"),level=4) + #mwf for interpolating subgrid error for gradients etc + if self.stabilization and self.stabilization.usesGradientStabilization: + self.timeIntegration = TimeIntegrationClass(self,integrateInterpolationPoints=True) + else: + self.timeIntegration = TimeIntegrationClass(self) + + if options != None: + self.timeIntegration.setFromOptions(options) + logEvent(memory("TimeIntegration","OneLevelTransport"),level=4) + logEvent("Calculating numerical quadrature formulas",2) + self.calculateQuadrature() + #lay out components/equations contiguously for now + self.offset = [0] + for ci in range(1,self.nc): + self.offset += [self.offset[ci-1]+self.nFreeDOF_global[ci-1]] + self.stride = [1 for ci in range(self.nc)] + #use contiguous layout of components for parallel, requires weak DBC's + # mql. Some ASSERTS to restrict the combination of the methods + if self.coefficients.STABILIZATION_TYPE > 0: + pass + #assert self.timeIntegration.isSSP == True, "If STABILIZATION_TYPE>0, use RKEV timeIntegration within VOF model" + #cond = 'levelNonlinearSolver' in dir(options) and (options.levelNonlinearSolver == + # ExplicitLumpedMassMatrixForRichards or options.levelNonlinearSolver == ExplicitConsistentMassMatrixForRichards) + #assert cond, "If STABILIZATION_TYPE>0, use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards or ExplicitConsistentMassMatrixForRichards" + try: + if 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards: + assert self.coefficients.LUMPED_MASS_MATRIX, "If levelNonlinearSolver=ExplicitLumpedMassMatrix, use LUMPED_MASS_MATRIX=True" + except: + pass + if self.coefficients.LUMPED_MASS_MATRIX == True: + cond = self.coefficients.STABILIZATION_TYPE == 2 + assert cond, "Use lumped mass matrix just with: STABILIZATION_TYPE=2 (smoothness based stab.)" + cond = 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards + assert cond, "Use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards when the mass matrix is lumped" + if self.coefficients.FCT == True: + cond = self.coefficients.STABILIZATION_TYPE > 0, "Use FCT just with STABILIZATION_TYPE>0; i.e., edge based stabilization" + # END OF ASSERTS + + # cek adding empty data member for low order numerical viscosity structures here for now + self.ML = None # lumped mass matrix + self.MC_global = None # consistent mass matrix + self.cterm_global = None + self.cterm_transpose_global = None + # dL_global and dC_global are not the full matrices but just the CSR arrays containing the non zero entries + self.residualComputed=False #TMP + self.dLow= None + self.fluxMatrix = None + self.uDotLow = None + self.uLow = None + self.dt_times_dC_minus_dL = None + self.min_s_bc = None + self.max_s_bc = None + # Aux quantity at DOFs to be filled by optimized code (MQL) + self.quantDOFs = np.zeros(self.u[0].dof.shape, 'd') + self.sLow = np.zeros(self.u[0].dof.shape, 'd') + self.sHigh = np.zeros(self.u[0].dof.shape, 'd') + self.sn = np.zeros(self.u[0].dof.shape, 'd') + comm = Comm.get() + self.comm=comm + if comm.size() > 1: + assert numericalFluxType != None and numericalFluxType.useWeakDirichletConditions,"You must use a numerical flux to apply weak boundary conditions for parallel runs" + self.offset = [0] + for ci in range(1,self.nc): + self.offset += [ci] + self.stride = [self.nc for ci in range(self.nc)] + # + logEvent(memory("stride+offset","OneLevelTransport"),level=4) + + #logEvent("Hi, this is Arnob") + if numericalFluxType != None: + if options is None or options.periodicDirichletConditions is None: + self.numericalFlux = numericalFluxType(self, + dofBoundaryConditionsSetterDict, + advectiveFluxBoundaryConditionsSetterDict, + diffusiveFluxBoundaryConditionsSetterDictDict) + else: + self.numericalFlux = numericalFluxType(self, + dofBoundaryConditionsSetterDict, + advectiveFluxBoundaryConditionsSetterDict, + diffusiveFluxBoundaryConditionsSetterDictDict, + options.periodicDirichletConditions) + else: + self.numericalFlux = None + #set penalty terms + #cek todo move into numerical flux initialization + if 'penalty' in self.ebq_global: + for ebN in range(self.mesh.nElementBoundaries_global): + for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): + self.ebq_global['penalty'][ebN,k] = old_div(self.numericalFlux.penalty_constant,(self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power)) + #penalty term + #cek move to Numerical flux initialization + if 'penalty' in self.ebqe: + for ebNE in range(self.mesh.nExteriorElementBoundaries_global): + ebN = self.mesh.exteriorElementBoundariesArray[ebNE] + for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): + self.ebqe['penalty'][ebNE,k] = old_div(self.numericalFlux.penalty_constant,self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power) + logEvent(memory("numericalFlux","OneLevelTransport"),level=4) + self.elementEffectiveDiametersArray = self.mesh.elementInnerDiametersArray + #use post processing tools to get conservative fluxes, None by default + from proteus import PostProcessingTools + self.velocityPostProcessor = PostProcessingTools.VelocityPostProcessingChooser(self) + logEvent(memory("velocity postprocessor","OneLevelTransport"),level=4) + #helper for writing out data storage + from proteus import Archiver + self.elementQuadratureDictionaryWriter = Archiver.XdmfWriter() + self.elementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() + self.exteriorElementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() + #TODO get rid of this + for ci,fbcObject in list(self.fluxBoundaryConditionsObjectsDict.items()): + self.ebqe[('advectiveFlux_bc_flag',ci)] = np.zeros(self.ebqe[('advectiveFlux_bc',ci)].shape,'i') + for t,g in list(fbcObject.advectiveFluxBoundaryConditionsDict.items()): + if ci in self.coefficients.advection: + self.ebqe[('advectiveFlux_bc',ci)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) + self.ebqe[('advectiveFlux_bc_flag',ci)][t[0],t[1]] = 1 + + if hasattr(self.numericalFlux,'setDirichletValues'): + self.numericalFlux.setDirichletValues(self.ebqe) + if not hasattr(self.numericalFlux,'isDOFBoundary'): + self.numericalFlux.isDOFBoundary = {0:np.zeros(self.ebqe[('u',0)].shape,'i')} + if not hasattr(self.numericalFlux,'ebqe'): + self.numericalFlux.ebqe = {('u',0):np.zeros(self.ebqe[('u',0)].shape,'d')} + #TODO how to handle redistancing calls for calculateCoefficients,calculateElementResidual etc + self.globalResidualDummy = None + compKernelFlag=0 + self.delta_x_ij=None + self.richards = cRichards_base(self.nSpace_global, + self.nQuadraturePoints_element, + self.u[0].femSpace.elementMaps.localFunctionSpace.dim, + self.u[0].femSpace.referenceFiniteElement.localFunctionSpace.dim, + self.testSpace[0].referenceFiniteElement.localFunctionSpace.dim, + self.nElementBoundaryQuadraturePoints_elementBoundary, + compKernelFlag) + if self.movingDomain: + self.MOVING_DOMAIN=1.0 + else: + self.MOVING_DOMAIN=0.0 + #cek hack + self.movingDomain=False + self.MOVING_DOMAIN=0.0 + if self.mesh.nodeVelocityArray is None: + self.mesh.nodeVelocityArray = np.zeros(self.mesh.nodeArray.shape,'d') + self.forceStrongConditions=True + self.dirichletConditionsForceDOF = {} + if self.forceStrongConditions: + for cj in range(self.nc): + self.dirichletConditionsForceDOF[cj] = DOFBoundaryConditions(self.u[cj].femSpace,dofBoundaryConditionsSetterDict[cj],weakDirichletConditions=False) + def FCTStep(self): + import pdb + rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() + limited_solution = np.zeros((len(rowptr) - 1),'d') + #self.u_free_dof_stage_0_l = np.zeros((len(rowptr) - 1),'d') + #self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage], # soln + #fromFreeToGlobal=0 + #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + # self.offset[0], + # self.stride[0], + # self.dirichletConditions[0].global2freeGlobal_global_dofs, + # self.dirichletConditions[0].global2freeGlobal_free_dofs, + # self.u_free_dof_stage_0_l, + # self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage]) + argsDict = cArgumentsDict.ArgumentsDict() + argsDict["bc_mask"] = self.bc_mask + argsDict["NNZ"] = self.nnz + argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs + argsDict["dt"] = self.timeIntegration.dt + argsDict["lumped_mass_matrix"] = self.ML + argsDict["soln"] = self.sn + argsDict["pn"] = self.u[0].dof + argsDict["solH"] = self.sHigh + argsDict["uLow"] = self.sLow + argsDict["uDotLow"] = self.uDotLow + argsDict["limited_solution"] = limited_solution + argsDict["csrRowIndeces_DofLoops"] = rowptr + argsDict["csrColumnOffsets_DofLoops"] = colind + argsDict["MassMatrix"] = MassMatrix + argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL + argsDict["min_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0]) #cek hack just set from physical bounds + argsDict["max_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0] + self.coefficients.thetaSR_types[0]) #cek hack + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["MONOLITHIC"] =0#cek hack self.coefficients.MONOLITHIC + #pdb.set_trace() + self.richards.FCTStep(argsDict) + + # self.nnz, # number of non zero entries + # len(rowptr) - 1, # number of DOFs + # self.timeIntegration.dt, + # self.ML, # Lumped mass matrix + # self.sn, + # self.u_dof_old, + # self.sHigh, # high order solution + # self.sLow, + # limited_solution, + # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) + # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) + # MassMatrix, + # self.dt_times_dC_minus_dL, + # self.min_s_bc, + # self.max_s_bc, + # self.coefficients.LUMPED_MASS_MATRIX, + # self.coefficients.MONOLITHIC) + old_dof = self.u[0].dof.copy() + self.invert(limited_solution, self.u[0].dof) + self.timeIntegration.u[:] = self.u[0].dof + #fromFreeToGlobal=1 #direction copying + #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + # self.offset[0], + # self.stride[0], + # self.dirichletConditions[0].global2freeGlobal_global_dofs, + # self.dirichletConditions[0].global2freeGlobal_free_dofs, + # self.u[0].dof, + # limited_solution) + def kth_FCT_step(self): + #import pdb + #pdb.set_trace() + rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() + limitedFlux = np.zeros(self.nnz) + limited_solution = np.zeros((len(rowptr) - 1),'d') + #limited_solution[:] = self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage] + fromFreeToGlobal=0 #direction copying + cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + self.offset[0], + self.stride[0], + self.dirichletConditions[0].global2freeGlobal_global_dofs, + self.dirichletConditions[0].global2freeGlobal_free_dofs, + limited_solution, + self.timeintegration.u_dof_stage[0][self.timeIntegration.lstage]) + + self.richards.kth_FCT_step( + self.timeIntegration.dt, + self.coefficients.num_fct_iter, + self.nnz, # number of non zero entries + len(rowptr) - 1, # number of DOFs + MassMatrix, + self.ML, # Lumped mass matrix + self.u_dof_old, + limited_solution, + self.uDotLow, + self.uLow, + self.dLow, + self.fluxMatrix, + limitedFlux, + rowptr, + colind) + + self.timeIntegration.u[:] = limited_solution + #self.u[0].dof[:] = limited_solution + fromFreeToGlobal=1 #direction copying + cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + self.offset[0], + self.stride[0], + self.dirichletConditions[0].global2freeGlobal_global_dofs, + self.dirichletConditions[0].global2freeGlobal_free_dofs, + self.u[0].dof, + limited_solution) + def calculateCoefficients(self): + pass + def calculateElementResidual(self): + if self.globalResidualDummy != None: + self.getResidual(self.u[0].dof,self.globalResidualDummy) + def getResidual(self,u,r): + import pdb + import copy + """ + Calculate the element residuals and add in to the global residual + """ + cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, + self.jacobian) + if self.u_dof_old is None: + # Pass initial condition to u_dof_old + self.u_dof_old = np.copy(self.u[0].dof) + rowptr, colind, nzval = self.jacobian.getCSRrepresentation() + nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix + r.fill(0.0) + ######################## + ### COMPUTE C MATRIX ### + ######################## + if self.cterm_global is None: + # since we only need cterm_global to persist, we can drop the other self.'s + self.cterm = {} + self.cterm_a = {} + self.cterm_global = {} + self.cterm_transpose = {} + self.cterm_a_transpose = {} + self.cterm_global_transpose = {} + rowptr, colind, nzval = self.jacobian.getCSRrepresentation() + nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix + di = self.q[('grad(u)', 0)].copy() # direction of derivative + # JACOBIANS (FOR ELEMENT TRANSFORMATION) + self.q[('J')] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nSpace_global, + self.nSpace_global), + 'd') + self.q[('inverse(J)')] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nSpace_global, + self.nSpace_global), + 'd') + self.q[('det(J)')] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element), + 'd') + self.u[0].femSpace.elementMaps.getJacobianValues(self.elementQuadraturePoints, + self.q['J'], + self.q['inverse(J)'], + self.q['det(J)']) + self.q['abs(det(J))'] = np.abs(self.q['det(J)']) + # SHAPE FUNCTIONS + self.q[('w', 0)] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nDOF_test_element[0]), + 'd') + self.q[('w*dV_m', 0)] = self.q[('w', 0)].copy() + self.u[0].femSpace.getBasisValues(self.elementQuadraturePoints, self.q[('w', 0)]) + cfemIntegrals.calculateWeightedShape(self.elementQuadratureWeights[('u', 0)], + self.q['abs(det(J))'], + self.q[('w', 0)], + self.q[('w*dV_m', 0)]) + # GRADIENT OF TEST FUNCTIONS + self.q[('grad(w)', 0)] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nDOF_test_element[0], + self.nSpace_global), + 'd') + self.u[0].femSpace.getBasisGradientValues(self.elementQuadraturePoints, + self.q['inverse(J)'], + self.q[('grad(w)', 0)]) + self.q[('grad(w)*dV_f', 0)] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nDOF_test_element[0], + self.nSpace_global), + 'd') + cfemIntegrals.calculateWeightedShapeGradients(self.elementQuadratureWeights[('u', 0)], + self.q['abs(det(J))'], + self.q[('grad(w)', 0)], + self.q[('grad(w)*dV_f', 0)]) + ########################## + ### LUMPED MASS MATRIX ### + ########################## + # assume a linear mass term + dm = np.ones(self.q[('u', 0)].shape, 'd') + elementMassMatrix = np.zeros((self.mesh.nElements_global, + self.nDOF_test_element[0], + self.nDOF_trial_element[0]), 'd') + cfemIntegrals.updateMassJacobian_weak_lowmem(dm, + self.q[('w', 0)], + self.q[('w*dV_m', 0)], + elementMassMatrix) + self.MC_a = nzval.copy() + self.MC_global = SparseMat(self.nFreeDOF_global[0], + self.nFreeDOF_global[0], + nnz, + self.MC_a, + colind, + rowptr) + cfemIntegrals.zeroJacobian_CSR(self.nnz, self.MC_global) + cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.csrRowIndeces[(0, 0)], + self.csrColumnOffsets[(0, 0)], + elementMassMatrix, + self.MC_global) + self.ML = np.zeros((self.nFreeDOF_global[0],), 'd') + for i in range(self.nFreeDOF_global[0]): + self.ML[i] = self.MC_a[rowptr[i]:rowptr[i + 1]].sum() + np.testing.assert_almost_equal(self.ML.sum(), + self.mesh.volume, + err_msg="Trace of lumped mass matrix should be the domain volume", verbose=True) + for d in range(self.nSpace_global): # spatial dimensions + # C matrices + self.cterm[d] = np.zeros((self.mesh.nElements_global, + self.nDOF_test_element[0], + self.nDOF_trial_element[0]), 'd') + self.cterm_a[d] = nzval.copy() + #self.cterm_a[d] = np.zeros(nzval.size) + self.cterm_global[d] = SparseMat(self.nFreeDOF_global[0], + self.nFreeDOF_global[0], + nnz, + self.cterm_a[d], + colind, + rowptr) + cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global[d]) + di[:] = 0.0 + di[..., d] = 1.0 + cfemIntegrals.updateHamiltonianJacobian_weak_lowmem(di, + self.q[('grad(w)*dV_f', 0)], + self.q[('w', 0)], + self.cterm[d]) # int[(di*grad(wj))*wi*dV] + cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.csrRowIndeces[(0, 0)], + self.csrColumnOffsets[(0, 0)], + self.cterm[d], + self.cterm_global[d]) + # C Transpose matrices + self.cterm_transpose[d] = np.zeros((self.mesh.nElements_global, + self.nDOF_test_element[0], + self.nDOF_trial_element[0]), 'd') + self.cterm_a_transpose[d] = nzval.copy() + self.cterm_global_transpose[d] = SparseMat(self.nFreeDOF_global[0], + self.nFreeDOF_global[0], + nnz, + self.cterm_a_transpose[d], + colind, + rowptr) + cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global_transpose[d]) + di[:] = 0.0 + di[..., d] = -1.0 + cfemIntegrals.updateAdvectionJacobian_weak_lowmem(di, + self.q[('w', 0)], + self.q[('grad(w)*dV_f', 0)], + self.cterm_transpose[d]) # -int[(-di*grad(wi))*wj*dV] + cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.csrRowIndeces[(0, 0)], + self.csrColumnOffsets[(0, 0)], + self.cterm_transpose[d], + self.cterm_global_transpose[d]) + + rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() + else: + Cy = np.zeros(Cx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() + else: + Cz = np.zeros(Cx.shape, 'd') + rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() + else: + CTy = np.zeros(CTx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() + else: + CTz = np.zeros(CTx.shape, 'd') + + # This is dummy. I just care about the csr structure of the sparse matrix + self.dLow = np.zeros(Cx.shape, 'd') + self.fluxMatrix = np.zeros(Cx.shape, 'd') + self.dt_times_dC_minus_dL = np.zeros(Cx.shape, 'd') + nFree = len(rowptr)-1 + self.min_s_bc = np.zeros(nFree, 'd') + 1E10 + self.max_s_bc = np.zeros(nFree, 'd') - 1E10 + self.uDotLow = np.zeros(nFree, 'd') + self.uLow = np.zeros(nFree, 'd') + # + # cek end computationa of cterm_global + # + # cek showing mquezada an example of using cterm_global sparse matrix + # calculation y = c*x where x==1 + # direction=0 + #rowptr, colind, c = self.cterm_global[direction].getCSRrepresentation() + #y = np.zeros((self.nFreeDOF_global[0],),'d') + #x = np.ones((self.nFreeDOF_global[0],),'d') + # ij=0 + # for i in range(self.nFreeDOF_global[0]): + # for offset in range(rowptr[i],rowptr[i+1]): + # j = colind[offset] + # y[i] += c[ij]*x[j] + # ij+=1 + #Load the unknowns into the finite element dof + self.timeIntegration.calculateCoefs() + self.timeIntegration.calculateU(u) + self.setUnknowns(self.timeIntegration.u) + #cek can put in logic to skip of BC's don't depend on t or u + #Dirichlet boundary conditions + self.numericalFlux.setDirichletValues(self.ebqe) + #flux boundary conditions + #cek hack, just using advective flux for flux BC for now + for t,g in list(self.fluxBoundaryConditionsObjectsDict[0].advectiveFluxBoundaryConditionsDict.items()): + self.ebqe[('advectiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) + self.ebqe[('advectiveFlux_bc_flag',0)][t[0],t[1]] = 1 + # for t,g in self.fluxBoundaryConditionsObjectsDict[0].diffusiveFluxBoundaryConditionsDict.iteritems(): + # self.ebqe[('diffusiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) + # self.ebqe[('diffusiveFlux_bc_flag',0)][t[0],t[1]] = 1 + #self.shockCapturing.lag=True + if self.forceStrongConditions: + self.bc_mask = np.ones_like(self.u[0].dof) + for cj in range(len(self.dirichletConditionsForceDOF)): + for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): + self.u[cj].dof[dofN] = g(self.dirichletConditionsForceDOF[cj].DOFBoundaryPointDict[dofN],self.timeIntegration.t) + self.u_dof_old[dofN] = self.u[cj].dof[dofN] + self.bc_mask[dofN] = 0.0 + degree_polynomial = 1 + try: + degree_polynomial = self.u[0].femSpace.order + except: + pass + + argsDict = cArgumentsDict.ArgumentsDict() + argsDict["bc_mask"] = self.bc_mask + argsDict["dt"] = self.timeIntegration.dt + argsDict["Theta"] = 1.0 + argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi + argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi + argsDict["mesh_dof"] = self.mesh.nodeArray + argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray + argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN + argsDict["mesh_l2g"] = self.mesh.elementNodesArray + argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] + argsDict["u_trial_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi + argsDict["u_test_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi + argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace + argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace + argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] + argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals + argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians + argsDict["nElements_global"] = self.mesh.nElements_global + argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] + argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, + argsDict["isSeepageFace"] = self.coefficients.isSeepageFace + argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] + argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] + argsDict["rho"] = self.coefficients.rho + argsDict["beta"] = self.coefficients.beta + argsDict["gravity"] = self.coefficients.gravity + argsDict["alpha"] = self.coefficients.vgm_alpha_types + argsDict["n"] = self.coefficients.vgm_n_types + argsDict["thetaR"] = self.coefficients.thetaR_types + argsDict["thetaSR"] = self.coefficients.thetaSR_types + argsDict["KWs"] = self.coefficients.Ksw_types + argsDict["useMetrics"] = 0.0 + argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf + argsDict["lag_shockCapturing"] = 0 + argsDict["shockCapturingDiffusion"] = 0.0 + argsDict["sc_uref"] = 0.0 + argsDict["sc_alpha"] = 0.0 + argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g + argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] + argsDict["elementDiameter"] = self.mesh.elementDiametersArray + argsDict["degree_polynomial"] = degree_polynomial + argsDict["u_dof"] = self.u[0].dof + argsDict["u_dof_old"] = self.u_dof_old + argsDict["velocity"] = self.q['velocity'] + argsDict["q_m"] = self.timeIntegration.m_tmp[0] + argsDict["q_u"] = self.q[('u',0)] + argsDict["q_dV"] = self.q[('dV_u',0)] + argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] + argsDict["cfl"] = self.q[('cfl',0)] + argsDict["q_numDiff_u"] = self.q[('cfl',0)] + argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] + argsDict["offset_u"] = self.offset[0] + argsDict["stride_u"] = self.stride[0] + argsDict["globalResidual"] = r + argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global + argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray + argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray + argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray + argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] + argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] + argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] + argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] + argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] + argsDict["ebqe_phi"] = self.ebqe[('u',0)] + argsDict["epsFact"] = 0.0 + argsDict["ebqe_u"] = self.ebqe[('u',0)] + argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] + argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE + # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION + argsDict["cE"] = self.coefficients.cE + argsDict["cK"] = self.coefficients.cK + # PARAMETERS FOR LOG BASED ENTROPY FUNCTION + argsDict["uL"] = self.coefficients.uL + argsDict["uR"] = self.coefficients.uR + # PARAMETERS FOR EDGE VISCOSITY + argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs + argsDict["NNZ"] = self.nnz + argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern + argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) + argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) + argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms + argsDict["globalJacobian"] = self.jacobian.getCSRrepresentation()[2] + # C matrices + argsDict["Cx"] = Cx + argsDict["Cy"] = Cy + argsDict["Cz"] = Cz + argsDict["CTx"] = CTx + argsDict["CTy"] = CTy + argsDict["CTz"] = CTz + argsDict["ML"] = self.ML + argsDict["delta_x_ij"] = self.delta_x_ij + # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE + argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE + # FLUX CORRECTED TRANSPORT + argsDict["dLow"] = self.dLow + argsDict["fluxMatrix"] = self.fluxMatrix + argsDict["uDotLow"] = self.uDotLow + argsDict["uLow"] = self.uLow + argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL + argsDict["min_s_bc"] = self.min_s_bc + argsDict["max_s_bc"] = self.max_s_bc + argsDict["quantDOFs"] = self.quantDOFs + argsDict["sLow"] = self.sLow + argsDict["sn"] = self.sn + + argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #print(anb_seepage_flux) + #argsDict["anb_seepage_flux_n"] = self.coefficients.anb_seepage_flux_n + + #print("Seepage Flux from Python file", self.coefficients.anb_seepage_flux) + + + if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG + self.calculateResidual = self.richards.calculateResidual + self.calculateJacobian = self.richards.calculateJacobian + else: + self.calculateResidual = self.richards.calculateResidual_entropy_viscosity + self.calculateJacobian = self.richards.calculateMassMatrix + if self.delta_x_ij is None: + self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') + self.calculateResidual(argsDict) + #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] + #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf + #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] + #self.timeIntegration.calculateElementCoefficients(self.q) + if self.forceStrongConditions:# + for cj in range(len(self.dirichletConditionsForceDOF)):# + for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): + r[self.offset[cj]+self.stride[cj]*dofN] = 0 + if self.stabilization: + self.stabilization.accumulateSubgridMassHistory(self.q) + logEvent("Global residual",level=9,data=r) + self.nonlinear_function_evaluations += 1 + if self.globalResidualDummy is None: + self.globalResidualDummy = np.zeros(r.shape,'d') + + #print("Hello from the python file", self.coefficients.anb_seepage_flux) + #logEvent("Hello from the python file", self.coefficients.anb_seepage_flux") + + + + + def invert(self,u,r): + #u=s + #r=p + import pdb + import copy + """ + Calculate the element residuals and add in to the global residual + """ + self.sHigh[:] = u + rowptr, colind, nzval = self.jacobian.getCSRrepresentation() + nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix + r.fill(0.0) + rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() + else: + Cy = np.zeros(Cx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() + else: + Cz = np.zeros(Cx.shape, 'd') + rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() + else: + CTy = np.zeros(CTx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() + else: + CTz = np.zeros(CTx.shape, 'd') + + # This is dummy. I just care about the csr structure of the sparse matrix + nFree = len(rowptr)-1 + degree_polynomial = 1 + try: + degree_polynomial = self.u[0].femSpace.order + except: + pass + if self.delta_x_ij is None: + self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') + argsDict = cArgumentsDict.ArgumentsDict() + argsDict["dt"] = self.timeIntegration.dt + argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi + argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi + argsDict["mesh_dof"] = self.mesh.nodeArray + argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray + argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN + argsDict["mesh_l2g"] = self.mesh.elementNodesArray + argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] + argsDict["u_trial_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi + argsDict["u_test_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi + argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace + argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace + argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] + argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals + argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians + argsDict["nElements_global"] = self.mesh.nElements_global + argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] + argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, + argsDict["isSeepageFace"] = self.coefficients.isSeepageFace + argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] + argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] + argsDict["rho"] = self.coefficients.rho + argsDict["beta"] = self.coefficients.beta + argsDict["gravity"] = self.coefficients.gravity + argsDict["alpha"] = self.coefficients.vgm_alpha_types + argsDict["n"] = self.coefficients.vgm_n_types + argsDict["thetaR"] = self.coefficients.thetaR_types + argsDict["thetaSR"] = self.coefficients.thetaSR_types + argsDict["KWs"] = self.coefficients.Ksw_types + argsDict["useMetrics"] = 0.0 + argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf + argsDict["lag_shockCapturing"] = 0 + argsDict["shockCapturingDiffusion"] = 0.0 + argsDict["sc_uref"] = 0.0 + argsDict["sc_alpha"] = 0.0 + argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g + argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] + argsDict["elementDiameter"] = self.mesh.elementDiametersArray + argsDict["degree_polynomial"] = degree_polynomial + argsDict["u_dof"] = u#self.u[0].dof + argsDict["u_dof_old"] = self.u[0].dof + argsDict["velocity"] = self.q['velocity'] + argsDict["q_m"] = self.timeIntegration.m_tmp[0] + argsDict["q_u"] = self.q[('u',0)] + argsDict["q_dV"] = self.q[('dV_u',0)] + argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] + argsDict["cfl"] = self.q[('cfl',0)] + argsDict["q_numDiff_u"] = self.q[('cfl',0)] + argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] + argsDict["offset_u"] = self.offset[0] + argsDict["stride_u"] = self.stride[0] + argsDict["globalResidual"] = r + argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global + argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray + argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray + argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray + argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] + argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] + argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] + argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] + argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] + argsDict["ebqe_phi"] = self.ebqe[('u',0)] + argsDict["epsFact"] = 0.0 + argsDict["ebqe_u"] = self.ebqe[('u',0)] + argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] + argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE + # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION + argsDict["cE"] = self.coefficients.cE + argsDict["cK"] = self.coefficients.cK + # PARAMETERS FOR LOG BASED ENTROPY FUNCTION + argsDict["uL"] = self.coefficients.uL + argsDict["uR"] = self.coefficients.uR + # PARAMETERS FOR EDGE VISCOSITY + argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs + argsDict["NNZ"] = self.nnz + argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern + argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) + argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) + argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms + # C matrices + argsDict["Cx"] = Cx + argsDict["Cy"] = Cy + argsDict["Cz"] = Cz + argsDict["CTx"] = CTx + argsDict["CTy"] = CTy + argsDict["CTz"] = CTz + argsDict["ML"] = self.ML + argsDict["delta_x_ij"] = self.delta_x_ij + # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE + argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE + # FLUX CORRECTED TRANSPORT + argsDict["dLow"] = self.dLow + argsDict["fluxMatrix"] = self.fluxMatrix + argsDict["uDotLow"] = self.uDotLow + argsDict["uLow"] = self.uLow + argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL + argsDict["min_s_bc"] = self.min_s_bc + argsDict["max_s_bc"] = self.max_s_bc + argsDict["quantDOFs"] = self.quantDOFs + argsDict["sLow"] = self.sLow + argsDict["sn"] = self.sn + #Arnob trying to print flux + argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #print("Hi",anb_seepage_flux) + #print("Hi Seepage Flux", self.coefficients.anb_seepage_flux) + + self.richards.invert(argsDict) + # self.timeIntegration.dt, + # self.u[0].femSpace.elementMaps.psi, + # self.u[0].femSpace.elementMaps.grad_psi, + # self.mesh.nodeArray, + # self.mesh.nodeVelocityArray, + # self.MOVING_DOMAIN, + # self.mesh.elementNodesArray, + # self.elementQuadratureWeights[('u',0)], + # self.u[0].femSpace.psi, + # self.u[0].femSpace.grad_psi, + # self.u[0].femSpace.psi, + # self.u[0].femSpace.grad_psi, + # #element boundary + # self.u[0].femSpace.elementMaps.psi_trace, + # self.u[0].femSpace.elementMaps.grad_psi_trace, + # self.elementBoundaryQuadratureWeights[('u',0)], + # self.u[0].femSpace.psi_trace, + # self.u[0].femSpace.grad_psi_trace, + # self.u[0].femSpace.psi_trace, + # self.u[0].femSpace.grad_psi_trace, + # self.u[0].femSpace.elementMaps.boundaryNormals, + # self.u[0].femSpace.elementMaps.boundaryJacobians, + # #physics + # self.mesh.nElements_global, + # self.ebqe['penalty'],#double* ebqe_penalty_ext, + # self.mesh.elementMaterialTypes,#int* elementMaterialTypes, + # self.coefficients.isSeepageFace, + # self.coefficients.sdInfo[(0,0)][0],#int* a_rowptr, + # self.coefficients.sdInfo[(0,0)][1],#int* a_colind, + # self.coefficients.rho,#double rho, + # self.coefficients.beta,#double beta, + # self.coefficients.gravity,#double* gravity, + # self.coefficients.vgm_alpha_types,#double* alpha, + # self.coefficients.vgm_n_types,#double* n, + # self.coefficients.thetaR_types,#double* thetaR, + # self.coefficients.thetaSR_types,#double* thetaSR, + # self.coefficients.Ksw_types,#double* KWs, + # False,#self.coefficients.useMetrics, + # self.timeIntegration.alpha_bdf, + # 0,#self.shockCapturing.lag, + # 0.0,#cek hack self.shockCapturing.shockCapturingFactor, + # 0.0,#self.coefficients.sc_uref, + # 0.0,#self.coefficients.sc_beta, + # self.u[0].femSpace.dofMap.l2g, + # self.l2g[0]['freeGlobal'], + # self.mesh.elementDiametersArray, + # degree_polynomial, + # self.sHigh, + # self.u_dof_old, + # self.q['velocity'],#self.coefficients.q_v, + # self.timeIntegration.m_tmp[0], + # self.q[('u',0)], + # self.timeIntegration.beta_bdf[0], + # self.q[('cfl',0)], + # self.edge_based_cfl, + # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff[0], + # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff_last[0], + # self.offset[0],self.stride[0], + # r, + # self.mesh.nExteriorElementBoundaries_global, + # self.mesh.exteriorElementBoundariesArray, + # self.mesh.elementBoundaryElementsArray, + # self.mesh.elementBoundaryLocalElementBoundariesArray, + # self.ebqe['velocity'],#self.coefficients.ebqe_v, + # self.numericalFlux.isDOFBoundary[0], + # self.numericalFlux.ebqe[('u',0)], + # self.ebqe[('advectiveFlux_bc_flag',0)], + # self.ebqe[('advectiveFlux_bc',0)], + # self.ebqe[('u',0)],#cek hack self.coefficients.ebqe_phi, + # 0.0,#cek hack self.coefficients.epsFact, + # self.ebqe[('u',0)], + # self.ebqe[('advectiveFlux',0)], + # # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION + # self.coefficients.cE, + # self.coefficients.cK, + # # PARAMETERS FOR LOG BASED ENTROPY FUNCTION + # self.coefficients.uL, + # self.coefficients.uR, + # # PARAMETERS FOR EDGE VISCOSITY + # len(rowptr) - 1, # num of DOFs + # len(Cx), # num of non-zero entries in the sparsity pattern + # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) + # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) + # self.csrRowIndeces[(0, 0)], # row indices (convenient for element loops) + # self.csrColumnOffsets[(0, 0)], # column indices (convenient for element loops) + # self.csrColumnOffsets_eb[(0, 0)], # indices for boundary terms + # # C matrices + # Cx, + # Cy, + # Cz, + # CTx, + # CTy, + # CTz, + # self.ML, + # self.delta_x_ij, + # # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + # self.coefficients.LUMPED_MASS_MATRIX, + # self.coefficients.STABILIZATION_TYPE, + # self.coefficients.ENTROPY_TYPE, + # # FLUX CORRECTED TRANSPORT + # self.dLow, + # self.fluxMatrix, + # self.uDotLow, + # self.uLow, + # self.dt_times_dC_minus_dL, + # self.min_s_bc, + # self.max_s_bc, + # self.quantDOFs) + #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] + #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf + #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] + #self.timeIntegration.calculateElementCoefficients(self.q) + #if self.forceStrongConditions:# + # for cj in range(len(self.dirichletConditionsForceDOF)):# + # for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): + # r[self.offset[cj]+self.stride[cj]*dofN] = 0 + #if self.stabilization: + # self.stabilization.accumulateSubgridMassHistory(self.q) + #logEvent("Global residual",level=9,data=r) + #self.nonlinear_function_evaluations += 1 + #if self.globalResidualDummy is None: + # self.globalResidualDummy = numpy.zeros(r.shape,'d') + def postStep(self, t, firstStep=False): + with open('seepage_flux_nnnn', "a") as f: + f.write("\n Time"+ ",\t" +"Seepage\n") + f.write(repr(t)+ ",\t" +repr(self.coefficients.anb_seepage_flux)) + def getJacobian(self,jacobian): + if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG + cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, + jacobian) + degree_polynomial = 1 + try: + degree_polynomial = self.u[0].femSpace.order + except: + pass + if self.delta_x_ij is None: + self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') + argsDict = cArgumentsDict.ArgumentsDict() + argsDict["dt"] = self.timeIntegration.dt + argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi + argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi + argsDict["mesh_dof"] = self.mesh.nodeArray + argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray + argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN + argsDict["mesh_l2g"] = self.mesh.elementNodesArray + argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] + argsDict["u_trial_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi + argsDict["u_test_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi + argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace + argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace + argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] + argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals + argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians + argsDict["nElements_global"] = self.mesh.nElements_global + argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] + argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, + argsDict["isSeepageFace"] = self.coefficients.isSeepageFace + argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] + argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] + argsDict["rho"] = self.coefficients.rho + argsDict["beta"] = self.coefficients.beta + argsDict["gravity"] = self.coefficients.gravity + argsDict["alpha"] = self.coefficients.vgm_alpha_types + argsDict["n"] = self.coefficients.vgm_n_types + argsDict["thetaR"] = self.coefficients.thetaR_types + argsDict["thetaSR"] = self.coefficients.thetaSR_types + argsDict["KWs"] = self.coefficients.Ksw_types + argsDict["useMetrics"] = 0.0 + argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf + argsDict["lag_shockCapturing"] = 0 + argsDict["shockCapturingDiffusion"] = 0.0 + argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g + argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] + argsDict["elementDiameter"] = self.mesh.elementDiametersArray + argsDict["degree_polynomial"] = degree_polynomial + argsDict["u_dof"] = self.u[0].dof + argsDict["velocity"] = self.q['velocity'] + argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] + argsDict["cfl"] = self.q[('cfl',0)] + argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] + argsDict["csrRowIndeces_u_u"] = self.csrRowIndeces[(0,0)] + argsDict["csrColumnOffsets_u_u"] = self.csrColumnOffsets[(0,0)] + argsDict["globalJacobian"] = jacobian.getCSRrepresentation()[2] + argsDict["delta_x_ij"] = self.delta_x_ij + argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global + argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray + argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray + argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray + argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] + argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] + argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] + argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] + argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] + argsDict["csrColumnOffsets_eb_u_u"] = self.csrColumnOffsets_eb[(0,0)] + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + + #arnob trying to calculate flux + #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #Arnob trying to print flux + #argsDict["anb_seepage_flux"] = self.calculateResidual.anb_seepage_flux + + #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #print("Hi Seepage Flux", self.coefficients.anb_seepage_flux) + #print("Hi Seepage Flux",anb_seepage_flux) + #print("The seepage is ", anb_seepage_flux) + + + + + self.calculateJacobian(argsDict) + if self.forceStrongConditions: + for dofN in list(self.dirichletConditionsForceDOF[0].DOFBoundaryConditionsDict.keys()): + global_dofN = self.offset[0]+self.stride[0]*dofN + self.nzval[np.where(self.colind == global_dofN)] = 0.0 #column + self.nzval[self.rowptr[global_dofN]:self.rowptr[global_dofN+1]] = 0.0 #row + zeroRow=True + for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]):#row + if (self.colind[i] == global_dofN): + self.nzval[i] = 1.0 + zeroRow = False + if zeroRow: + raise RuntimeError("Jacobian has a zero row because sparse matrix has no diagonal entry at row "+repr(global_dofN)+". You probably need add diagonal mass or reaction term") + #scaling = 1.0#probably want to add some scaling to match non-dirichlet diagonals in linear system + #for cj in range(self.nc): + # for dofN in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.keys()): + # global_dofN = self.offset[cj]+self.stride[cj]*dofN + # for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]): + # if (self.colind[i] == global_dofN): + # self.nzval[i] = scaling + # else: + # self.nzval[i] = 0.0 + logEvent("Jacobian ",level=10,data=jacobian) + #mwf decide if this is reasonable for solver statistics + self.nonlinear_function_jacobian_evaluations += 1 + return jacobian + def calculateElementQuadrature(self): + """ + Calculate the physical location and weights of the quadrature rules + and the shape information at the quadrature points. + + This function should be called only when the mesh changes. + """ + #self.u[0].femSpace.elementMaps.getValues(self.elementQuadraturePoints, + # self.q['x']) + self.u[0].femSpace.elementMaps.getBasisValuesRef(self.elementQuadraturePoints) + self.u[0].femSpace.elementMaps.getBasisGradientValuesRef(self.elementQuadraturePoints) + self.u[0].femSpace.getBasisValuesRef(self.elementQuadraturePoints) + self.u[0].femSpace.getBasisGradientValuesRef(self.elementQuadraturePoints) + self.coefficients.initializeElementQuadrature(self.timeIntegration.t,self.q) + if self.stabilization != None: + self.stabilization.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) + self.stabilization.initializeTimeIntegration(self.timeIntegration) + if self.shockCapturing != None: + self.shockCapturing.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) + def calculateElementBoundaryQuadrature(self): + pass + def calculateExteriorElementBoundaryQuadrature(self): + """ + Calculate the physical location and weights of the quadrature rules + and the shape information at the quadrature points on global element boundaries. + + This function should be called only when the mesh changes. + """ + # + #get physical locations of element boundary quadrature points + # + #assume all components live on the same mesh + self.u[0].femSpace.elementMaps.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.elementMaps.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.elementMaps.getValuesGlobalExteriorTrace(self.elementBoundaryQuadraturePoints, + self.ebqe['x']) + self.fluxBoundaryConditionsObjectsDict = dict([(cj,FluxBoundaryConditions(self.mesh, + self.nElementBoundaryQuadraturePoints_elementBoundary, + self.ebqe[('x')], + getAdvectiveFluxBoundaryConditions=self.advectiveFluxBoundaryConditionsSetterDict[cj], + getDiffusiveFluxBoundaryConditions=self.diffusiveFluxBoundaryConditionsSetterDictDict[cj])) + for cj in list(self.advectiveFluxBoundaryConditionsSetterDict.keys())]) + self.coefficients.initializeGlobalExteriorElementBoundaryQuadrature(self.timeIntegration.t,self.ebqe) + #argsDict = cArgumentsDict.ArgumentsDict() + #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #print("Hi", self.coefficients.anb_seepage_flux) + + #print("The seepage is ", anb_seepage_flux) + def estimate_mt(self): + pass + def calculateSolutionAtQuadrature(self): + pass + def calculateAuxiliaryQuantitiesAfterStep(self): + pass + def postStep(self, t, firstStep=False): + with open('seepage_flux_nnnnk', "a") as f: + f.write("\n Time"+ ",\t" +"Seepage\n") + f.write(repr(t)+ ",\t" +repr(self.coefficients.anb_seepage_flux)) + + + +#argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux +#anb_seepage_flux= self.coefficients.anb_seepage_flux +#print("Hi",anb_seepage_flux) + + +#print("Hello from the python file", self.coefficients.anb_seepage_flux) diff --git a/richards_fct/richards/edit/__init__.py b/richards_fct/richards/edit/__init__.py new file mode 100755 index 0000000000..c45e66de51 --- /dev/null +++ b/richards_fct/richards/edit/__init__.py @@ -0,0 +1,6 @@ +""" +Modules for simulating variably saturated single-phase flow +""" + +__all__ = ["Richards", + "cRichards"] diff --git a/richards_fct/richards/edit/cRichards.cpp b/richards_fct/richards/edit/cRichards.cpp new file mode 100755 index 0000000000..21c500c55c --- /dev/null +++ b/richards_fct/richards/edit/cRichards.cpp @@ -0,0 +1,36 @@ +#include "pybind11/pybind11.h" +#include "pybind11/stl_bind.h" + +#define FORCE_IMPORT_ARRAY +#include "Richards.h" + +#if defined(__GNUC__) && !defined(__clang__) + namespace workaround + { + inline void define_allocators() + { + std::allocator a0; + std::allocator a1; + } + } +#endif + + +namespace py = pybind11; +using proteus::Richards_base; +PYBIND11_MODULE(cRichards, m) +{ + xt::import_numpy(); + + py::class_(m, "cRichards_base") + .def(py::init(&proteus::newRichards)) + .def("calculateResidual", &Richards_base::calculateResidual) + .def("calculateJacobian", &Richards_base::calculateJacobian) + .def("invert", &Richards_base::invert) + .def("FCTStep", &Richards_base::FCTStep) + .def("kth_FCT_step", &Richards_base::kth_FCT_step) + .def("calculateResidual_entropy_viscosity", &Richards_base::calculateResidual_entropy_viscosity) + .def("calculateMassMatrix", &Richards_base::calculateMassMatrix); +} + + diff --git a/richards_fct/richards/new_update/Richards.h b/richards_fct/richards/new_update/Richards.h new file mode 100644 index 0000000000..d9e6a76a4a --- /dev/null +++ b/richards_fct/richards/new_update/Richards.h @@ -0,0 +1,2966 @@ +#ifndef Richards_H +#define Richards_H +#include +#include +#include +#include "CompKernel.h" +#include "ModelFactory.h" +#include "../mprans/ArgumentsDict.h" +#include "xtensor-python/pyarray.hpp" +#define nnz nSpace + +namespace py = pybind11; +#define POWER_SMOOTHNESS_INDICATOR 2 +#define IS_BETAij_ONE 0 +#define GLOBAL_FCT 0 +namespace proteus +{ + // Power entropy // + inline double ENTROPY(const double& phi, const double& phiL, const double& phiR){ + return 1./2.*std::pow(fabs(phi),2.); + } + inline double DENTROPY(const double& phi, const double& phiL, const double& phiR){ + return fabs(phi)*(phi>=0 ? 1 : -1); + } + // Log entropy // for level set from 0 to 1 + inline double ENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ + return std::log(fabs((phi-phiL)*(phiR-phi))+1E-14); + } + inline double DENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ + return (phiL+phiR-2*phi)*((phi-phiL)*(phiR-phi)>=0 ? 1 : -1)/(fabs((phi-phiL)*(phiR-phi))+1E-14); + } +} + +namespace proteus +{ + class Richards_base + { + //The base class defining the interface + public: + virtual ~Richards_base(){} + virtual void calculateResidual(arguments_dict& args)=0; + virtual void calculateJacobian(arguments_dict& args)=0; + virtual void invert(arguments_dict& args)=0; + virtual void FCTStep(arguments_dict& args)=0; + virtual void kth_FCT_step(arguments_dict& args)=0; + virtual void calculateResidual_entropy_viscosity(arguments_dict& args)=0; + virtual void calculateMassMatrix(arguments_dict& args)=0; + }; + + template + class Richards : public Richards_base + { + public: + const int nDOF_test_X_trial_element; + CompKernelType ck; + Richards(): + nDOF_test_X_trial_element(nDOF_test_element*nDOF_trial_element), + ck() + {} + inline + void evaluateCoefficients(const int rowptr[nSpace], + const int colind[nnz], + const double rho, + const double beta, + const double gravity[nSpace], + const double alpha, + const double n_vg, + const double thetaR, + const double thetaSR, + const double KWs[nnz], + const double& u, + double& m, + double& dm, + double f[nSpace], + double df[nSpace], + double a[nnz], + double da[nnz], + double as[nnz], + double& kr, + double& dkr) + { + const int nSpace2 = nSpace * nSpace; + double psiC; + double pcBar; + double pcBar_n; + double pcBar_nM1; + double pcBar_nM2; + double onePlus_pcBar_n; + double sBar; + double sqrt_sBar; + double DsBar_DpsiC; + double thetaW; + double DthetaW_DpsiC; + double vBar; + double vBar2; + double DvBar_DpsiC; + double KWr; + double DKWr_DpsiC; + double rho2 = rho * rho; + double thetaS; + double rhom; + double drhom; + double m_vg; + double pcBarStar; + double sqrt_sBarStar; + + psiC = -u; + m_vg = 1.0 - 1.0 / n_vg; + thetaS = thetaR + thetaSR; + if (psiC > 0.0) + { + pcBar = alpha * psiC; + pcBarStar = pcBar; + if (pcBar < 1.0e-8) + pcBarStar = 1.0e-8; + pcBar_nM2 = pow(pcBarStar, n_vg - 2); + pcBar_nM1 = pcBar_nM2 * pcBar; + pcBar_n = pcBar_nM1 * pcBar; + onePlus_pcBar_n = 1.0 + pcBar_n; + + sBar = pow(onePlus_pcBar_n, -m_vg); + /* using -mn = 1-n */ + DsBar_DpsiC = alpha * (1.0 - n_vg) * (sBar/onePlus_pcBar_n)*pcBar_nM1; + + vBar = 1.0-pcBar_nM1*sBar; + vBar2 = vBar*vBar; + DvBar_DpsiC = -alpha*(n_vg-1.0)*pcBar_nM2*sBar - pcBar_nM1*DsBar_DpsiC; + + thetaW = thetaSR*sBar + thetaR; + DthetaW_DpsiC = thetaSR * DsBar_DpsiC; + + sqrt_sBar = sqrt(sBar); + sqrt_sBarStar = sqrt_sBar; + if (sqrt_sBar < 1.0e-8) + sqrt_sBarStar = 1.0e-8; + KWr= sqrt_sBar*vBar2; + DKWr_DpsiC= ((0.5/sqrt_sBarStar)*DsBar_DpsiC*vBar2 + + + 2.0*sqrt_sBar*vBar*DvBar_DpsiC); + } + else + { + thetaW = thetaS; + DthetaW_DpsiC = 0.0; + KWr = 1.0; + DKWr_DpsiC = 0.0; + } + //slight compressibility + rhom = rho*exp(beta*u); + drhom = beta*rhom; + m = rhom*thetaW; + dm = -rhom*DthetaW_DpsiC+drhom*thetaW; + for (int I=0;I thetaS || thetaW <= thetaR) + { + //cek debug + std::cout<<"rho "< 0.0) + { + isDOFBoundary = 1; + bc_u = bc_u_seepage; + } + else + { + isDOFBoundary = 0; + flux = 0.0; + } + } + /* //set DOF flag and flux correctly if seepage face */ + /* if (isSeepageFace) */ + /* { */ + /* if (flux < 0.0 || u < bc_u_seepage) */ + /* { */ + /* isDOFBoundary = 0; */ + /* flux = 0.0; */ + /* } */ + /* else */ + /* { */ + /* isDOFBoundary = 1; */ + /* bc_u = bc_u_seepage; */ + /* } */ + /* } */ + /* //Dirichlet penalty */ + /* if (isDOFBoundary) */ + /* flux += penalty*(u-bc_u); */ + } + else + flux = bc_flux; + } + + void exteriorNumericalFluxJacobian(const int rowptr[nSpace], + const int colind[nnz], + const int isDOFBoundary, + const double n[nSpace], + const double K[nnz], + const double dK[nnz], + const double grad_psi[nSpace], + const double grad_v[nSpace], + const double dK_rho_g[nSpace], + const double v, + const double penalty, + double& fluxJacobian) + { + if (isDOFBoundary) + { + fluxJacobian = 0.0; + for(int I=0;I& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + double sc_uref = args.scalar("sc_uref"); + double sc_alpha = args.scalar("sc_alpha"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& u_dof_old = args.array("u_dof_old"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m = args.array("q_m"); + xt::pyarray& q_u = args.array("q_u"); + xt::pyarray& q_dV = args.array("q_dV"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + int offset_u = args.scalar("offset_u"); + int stride_u = args.scalar("stride_u"); + xt::pyarray& globalResidual = args.array("globalResidual"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& ebqe_phi = args.array("ebqe_phi"); + double epsFact = args.scalar("epsFact"); + xt::pyarray& ebqe_u = args.array("ebqe_u"); + xt::pyarray& ebqe_flux = args.array("ebqe_flux"); + // PARAMETERS FOR EDGE BASED STABILIZATION + double cE = args.scalar("cE"); + double cK = args.scalar("cK"); + // PARAMETERS FOR LOG BASED ENTROPY FUNCTION + double uL = args.scalar("uL"); + double uR = args.scalar("uR"); + // PARAMETERS FOR EDGE VISCOSITY + int numDOFs = args.scalar("numDOFs"); + int NNZ = args.scalar("NNZ"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); + xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); + xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); + xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); + // C matrices + xt::pyarray& Cx = args.array("Cx"); + xt::pyarray& Cy = args.array("Cy"); + xt::pyarray& Cz = args.array("Cz"); + xt::pyarray& CTx = args.array("CTx"); + xt::pyarray& CTy = args.array("CTy"); + xt::pyarray& CTz = args.array("CTz"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); + int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); + // FOR FCT + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& fluxMatrix = args.array("fluxMatrix"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); + xt::pyarray& min_s_bc = args.array("min_s_bc"); + xt::pyarray& max_s_bc = args.array("max_s_bc"); + // AUX QUANTITIES OF INTEREST + xt::pyarray& quantDOFs = args.array("quantDOFs"); + xt::pyarray& sLow = args.array("sLow"); + xt::pyarray& sn = args.array("sn"); + + assert(a_rowptr.data()[nSpace] == nnz); + assert(a_rowptr.data()[nSpace] == nSpace); + //cek should this be read in? + double Ct_sge = 4.0; + + //loop over elements to compute volume integrals and load them into element and global residual + // + //eN is the element index + //eN_k is the quadrature point index for a scalar + //eN_k_nSpace is the quadrature point index for a vector + //eN_i is the element test function index + //eN_j is the element trial function index + //eN_k_j is the quadrature point index for a trial function + //eN_k_i is the quadrature point index for a trial function + for(int eN=0;eN& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); + xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); + xt::pyarray& globalJacobian = args.array("globalJacobian"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + assert(a_rowptr.data()[nSpace] == nnz); + assert(a_rowptr.data()[nSpace] == nSpace); + double Ct_sge = 4.0; + + // + //loop over elements to compute volume integrals and load them into the element Jacobians and global Jacobian + // + for(int eN=0;eN& bc_mask = args.array("bc_mask"); + int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern + int numDOFs = args.scalar("numDOFs"); //number of DOFs + double dt = args.scalar("dt"); + xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) + xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn + xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn + xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& limited_solution = args.array("limited_solution"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets + xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices + xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 + xt::pyarray& max_s_bc = args.array("max_s_bc"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int MONOLITHIC = args.scalar("MONOLITHIC"); + register double Rpos[numDOFs], Rneg[numDOFs]; + register double FluxCorrectionMatrix[NNZ]; + register double solL[numDOFs]; + register double sdot[numDOFs]; + ////////////////// + // LOOP in DOFs // + ////////////////// + int ij=0; + for (int i=0; i 0) ? 1. : 0.); + Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); + + //update ij + ij+=1; + //std::cout<<"sdoti error"<0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])) + * FluxCorrectionMatrix[ij]; + alpha_dot = fmin(1.0, beta_ij*fabs(alpha_fA)/MassMatrix.data()[ij]/fmax(1.0e-8,fabs(sdoti-sdotj))); + if (MONOLITHIC == 0) + { + ith_Limiter_times_FluxCorrectionMatrix += alpha_fA; + } + else + { + ith_Limiter_times_FluxCorrectionMatrix += alpha_fA + (LUMPED_MASS_MATRIX == 1 ? 0. : 1.)*dt*alpha_dot*MassMatrix.data()[ij]*(sdoti-sdotj); + } + //update ij + ij+=1; + } + limited_solution.data()[i] = solL[i] + 1./lumped_mass_matrix.data()[i]*ith_Limiter_times_FluxCorrectionMatrix*bc_mask[i]; + } + } + + void kth_FCT_step(arguments_dict& args) + { + int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern + int numDOFs = args.scalar("numDOFs"); //number of DOFs + int num_fct_iter = args.scalar("num_fct_iter"); + double dt = args.scalar("dt"); + xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) + xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn + xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn + xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& solLim = args.array("limited_solution"); + xt::pyarray& MC = args.array("MC"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& FluxMatrix = args.array("FluxMatrix"); + xt::pyarray& limitedFlux = args.array("limited_Flux"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets + xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices + xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 + xt::pyarray& max_s_bc = args.array("max_s_bc"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int MONOLITHIC = args.scalar("MONOLITHIC"); + register double Rpos[numDOFs], Rneg[numDOFs]; + int ij=0; + + ////////////////////////////////////////////////////// + // ********** COMPUTE LOW ORDER SOLUTION ********** // + ////////////////////////////////////////////////////// + if (num_fct_iter == 0) + { // No FCT for global bounds + for (int i=0; i 0) ? 1. : 0.); + // update ij + ij+=1; + } + // compute Q vectors + double mi = ML.data()[i]; + double solLimi = solLim.data()[i]; + double Qposi = mi*(maxi-solLimi); + // compute R vectors + Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + } + ij=0; + for (int i=0; i0 ? Rposi : Rpos[j]); + // compute limited flux + ith_Limiter_times_FluxCorrectionMatrix += Lij*Fluxij; + + // update limited flux + limitedFlux.data()[ij] = Lij*Fluxij; + + //update FluxMatrix + FluxMatrix.data()[ij] = Fluxij; + + //update ij + ij+=1; + } + //update limited solution + double mi = ML.data()[i]; + solLim.data()[i] += 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; + } + } + } + + // ***************************************** // + // ********** HIGH ORDER SOLUTION ********** // + // ***************************************** // + ij=0; + for (int i=0; i 0 ? 1. : 0.); + Pnegi += fij * (fij < 0 ? 1. : 0.); + //update ij + ij+=1; + } + // compute Q vectors // + double mi = ML.data()[i]; + double Qposi = mi*(maxi-solLim.data()[i]); + double Qnegi = mi*(mini-solLim.data()[i]); + // compute R vectors // + Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); + } + + // COMPUTE LIMITERS // + ij=0; + for (int i=0; i 0 ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j]); + // compute ith_limited_flux_correction + ith_limited_flux_correction += Lij*fij; + ij+=1; + } + double mi = ML.data()[i]; + solLim[i] += 1./mi*ith_limited_flux_correction; + } + } + + void calculateResidual_entropy_viscosity(arguments_dict& args) + { + xt::pyarray& globalJacobian = args.array("globalJacobian"); + double Theta = args.scalar("Theta"); + xt::pyarray& bc_mask = args.array("bc_mask"); + double dt = args.scalar("dt"); + xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + int nElements_global = args.scalar("nElements_global"); + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + double sc_uref = args.scalar("sc_uref"); + double sc_alpha = args.scalar("sc_alpha"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& r_l2g = args.array("r_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + int degree_polynomial = args.scalar("degree_polynomial"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& u_dof_old = args.array("u_dof_old"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m = args.array("q_m"); + xt::pyarray& q_u = args.array("q_u"); + xt::pyarray& q_dV = args.array("q_dV"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + int offset_u = args.scalar("offset_u"); + int stride_u = args.scalar("stride_u"); + xt::pyarray& globalResidual = args.array("globalResidual"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& ebqe_phi = args.array("ebqe_phi"); + double epsFact = args.scalar("epsFact"); + xt::pyarray& ebqe_u = args.array("ebqe_u"); + xt::pyarray& ebqe_flux = args.array("ebqe_flux"); + // PARAMETERS FOR EDGE BASED STABILIZATION + double cE = args.scalar("cE"); + double cK = args.scalar("cK"); + // PARAMETERS FOR LOG BASED ENTROPY FUNCTION + double uL = args.scalar("uL"); + double uR = args.scalar("uR"); + // PARAMETERS FOR EDGE VISCOSITY + int numDOFs = args.scalar("numDOFs"); + int NNZ = args.scalar("NNZ"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); + xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); + xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); + xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); + // C matrices + xt::pyarray& Cx = args.array("Cx"); + xt::pyarray& Cy = args.array("Cy"); + xt::pyarray& Cz = args.array("Cz"); + xt::pyarray& CTx = args.array("CTx"); + xt::pyarray& CTy = args.array("CTy"); + xt::pyarray& CTz = args.array("CTz"); + xt::pyarray& ML = args.array("ML"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); + int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); + // FOR FCT + xt::pyarray& dLow = args.array("dLow"); + xt::pyarray& fluxMatrix = args.array("fluxMatrix"); + xt::pyarray& uDotLow = args.array("uDotLow"); + xt::pyarray& uLow = args.array("uLow"); + xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); + xt::pyarray& min_s_bc = args.array("min_s_bc"); + xt::pyarray& max_s_bc = args.array("max_s_bc"); + // AUX QUANTITIES OF INTEREST + xt::pyarray& quantDOFs = args.array("quantDOFs"); + xt::pyarray& sLow = args.array("sLow"); + xt::pyarray& sn = args.array("sn"); + register double Rpos[numDOFs], Rneg[numDOFs]; + //register double FluxCorrectionMatrix[NNZ]; + // NOTE: This function follows a different (but equivalent) implementation of the smoothness based indicator than NCLS.h + // Allocate space for the transport matrices + // This is used for first order KUZMIN'S METHOD + register double TransportMatrix[NNZ],TransportMatrixConsistent[NNZ]; + register double TransportMatrixn[NNZ],TransportMatrixConsistentn[NNZ]; + std::valarray u_free_dof(numDOFs); + std::valarray u_free_dof_old(numDOFs); + std::valarray ML2(numDOFs); + for(int eN=0;eN= 0 && isFluxBoundary_u[ebNE_kb] != 1 ) //outflow. This is handled via the transport matrices. Then flux_ext=0 and dflux_ext!=0 */ + /* { */ + /* dflux_ext = flow; */ + /* flux_ext = 0; */ + /* // save external u */ + /* ebqe_u[ebNE_kb] = u_ext; */ + /* } */ + /* else // inflow. This is handled via the boundary integral. Then flux_ext!=0 and dflux_ext=0 */ + /* { */ + /* dflux_ext = 0; */ + /* // save external u */ + /* ebqe_u[ebNE_kb] = isDOFBoundary_u[ebNE_kb]*ebqe_bc_u_ext[ebNE_kb]+(1-isDOFBoundary_u[ebNE_kb])*u_ext; */ + /* if (isDOFBoundary_u[ebNE_kb] == 1) */ + /* flux_ext = ebqe_bc_u_ext[ebNE_kb]*flow; */ + /* else if (isFluxBoundary_u[ebNE_kb] == 1) */ + /* flux_ext = ebqe_bc_flux_u_ext[ebNE_kb]; */ + /* else */ + /* { */ + /* std::cout<<"warning: VOF open boundary with no external trace, setting to zero for inflow"<= 0.) + { + alpha_numerator_pos += alpha_num; + alpha_denominator_pos += alpha_num; + } + else + { + alpha_numerator_neg += alpha_num; + alpha_denominator_neg += fabs(alpha_num); + } + //update ij + ij+=1; + } + // scale g vector by lumped mass matrix + if (fabs(ML.data()[i] - ML2[i]) > 1.0e-16) + std::cout<<"ML "< 0.0) + // assert( (xi[I] - xj[I]) == delta_x_ij[offset*3+I]); + //gi_times_x += gi[I]*(xi[I]-xj[I]); + gi_times_x += gi[I]*delta_x_ij.data()[offset*3+I]; + } + // compute the positive and negative part of gi*(xi-xj) + SumPos += gi_times_x > 0 ? gi_times_x : 0; + SumNeg += gi_times_x < 0 ? gi_times_x : 0; + } + double sigmaPosi = fmin(1.,(fabs(SumNeg)+1E-15)/(SumPos+1E-15)); + double sigmaNegi = fmin(1.,(SumPos+1E-15)/(fabs(SumNeg)+1E-15)); + double alpha_numi = fabs(sigmaPosi*alpha_numerator_pos + sigmaNegi*alpha_numerator_neg); + double alpha_deni = sigmaPosi*alpha_denominator_pos + sigmaNegi*alpha_denominator_neg; + if (IS_BETAij_ONE == 1) + { + alpha_numi = fabs(alpha_numerator_pos + alpha_numerator_neg); + alpha_deni = alpha_denominator_pos + alpha_denominator_neg; + } + double alphai = alpha_numi/(alpha_deni+1E-15); + quantDOFs.data()[i] = alphai; + + if (POWER_SMOOTHNESS_INDICATOR==0) + psi[i] = 1.0; + else + psi[i] = std::pow(alphai,POWER_SMOOTHNESS_INDICATOR); //NOTE: they use alpha^2 in the paper + } + ///////////////////////////////////////////// + // ** LOOP IN DOFs FOR EDGE BASED TERMS ** // + ///////////////////////////////////////////// + ij=0; + for (int i=0; i Dissipation matrices as well. + double soli = u_free_dof[i]; // solution at time tn for the ith DOF + double solni = u_free_dof_old[i]; // solution at time tn for the ith DOF + for (int I=0;I mMax) + { + std::cout<<"mass out of bounds "< 0) ? 1. : 0.); + // Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); + // ij+=1; + // } + // double mi = ML[i]; + // double solni = u_dof_old[i]; + // double Qposi = mi*(maxi-solni); + // double Qnegi = mi*(mini-solni); + + //std::cout << Qposi << std::endl; + // Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + // Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); + + //if (Rpos[i] < 0) + //{ + // std::cout << mi << "\t" << maxi << "\t" << solni << std::endl; + // std::cout << Qposi << "\t" << Pposi << std::endl; + // std::cout << Rpos[i] << std::endl; + //abort(); + //} + //} + + //ij=0; + //for (int i=0; i 1.0 || Rposi < 0.0) + //std::cout << "Rposi: " << Rposi << std::endl; + //if (Rnegi > 1.0 || Rnegi < 0.0) + //std::cout << "Rnegi: " << Rnegi << std::endl; + + // LOOP OVER THE SPARSITY PATTERN (j-LOOP)// + // for (int offset=csrRowIndeces_DofLoops.data()[i]; + // offset0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])); + // //Lij=0.0; + // ith_Limiter_times_FluxCorrectionMatrix += Lij*FluxCorrectionMatrix[ij]; + // //update ij + // ij+=1; + // } + // double mi = ML[i]; + // double solni = u_dof_old[i]; + // globalResidual[i] = solni + 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; + //} + + } + + void invert(arguments_dict& args) + { + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + xt::pyarray& globalResidual = args.array("globalResidual"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + int numDOFs = args.scalar("numDOFs"); + for (int i=0; i mMax) + { + std::cout<<"mass out of bounds "<("dt"); + xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); + xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); + xt::pyarray& mesh_dof = args.array("mesh_dof"); + xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); + double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); + xt::pyarray& mesh_l2g = args.array("mesh_l2g"); + xt::pyarray& dV_ref = args.array("dV_ref"); + xt::pyarray& u_trial_ref = args.array("u_trial_ref"); + xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); + xt::pyarray& u_test_ref = args.array("u_test_ref"); + xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); + //element boundary + xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); + xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); + xt::pyarray& dS_ref = args.array("dS_ref"); + xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); + xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); + xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); + xt::pyarray& normal_ref = args.array("normal_ref"); + xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); + //physics + int nElements_global = args.scalar("nElements_global"); + //new + xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); + xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); + xt::pyarray& isSeepageFace = args.array("isSeepageFace"); + xt::pyarray& a_rowptr = args.array("a_rowptr"); + xt::pyarray& a_colind = args.array("a_colind"); + double rho = args.scalar("rho"); + double beta = args.scalar("beta"); + xt::pyarray& gravity = args.array("gravity"); + xt::pyarray& alpha = args.array("alpha"); + xt::pyarray& n = args.array("n"); + xt::pyarray& thetaR = args.array("thetaR"); + xt::pyarray& thetaSR = args.array("thetaSR"); + xt::pyarray& KWs = args.array("KWs"); + //end new + double useMetrics = args.scalar("useMetrics"); + double alphaBDF = args.scalar("alphaBDF"); + int lag_shockCapturing = args.scalar("lag_shockCapturing"); + double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); + xt::pyarray& u_l2g = args.array("u_l2g"); + xt::pyarray& r_l2g = args.array("r_l2g"); + xt::pyarray& elementDiameter = args.array("elementDiameter"); + int degree_polynomial = args.scalar("degree_polynomial"); + xt::pyarray& u_dof = args.array("u_dof"); + xt::pyarray& velocity = args.array("velocity"); + xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); + xt::pyarray& cfl = args.array("cfl"); + xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); + xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); + xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); + xt::pyarray& globalJacobian = args.array("globalJacobian"); + xt::pyarray& delta_x_ij = args.array("delta_x_ij"); + int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); + xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); + xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); + xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); + xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); + xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); + xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); + xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); + xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); + xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); + int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + //std::cout<<"ndjaco address "<(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + else if (nSpaceIn == 2) + return proteus::chooseAndAllocateDiscretization2D(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + else + { + assert(nSpaceIn == 3); + return proteus::chooseAndAllocateDiscretization(nSpaceIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, + CompKernelFlag); + } + } +}//proteus +#endif diff --git a/richards_fct/richards/new_update/Richards.py b/richards_fct/richards/new_update/Richards.py new file mode 100644 index 0000000000..841fcd0884 --- /dev/null +++ b/richards_fct/richards/new_update/Richards.py @@ -0,0 +1,1745 @@ +from __future__ import division +from builtins import range +from past.utils import old_div +import proteus +from .cRichards import * +import numpy as np +from proteus.Transport import OneLevelTransport +from proteus.Transport import TC_base, NonlinearEquation, logEvent, memory +from proteus.Transport import FluxBoundaryConditions, Comm, cfemIntegrals +from proteus.Transport import DOFBoundaryConditions, Quadrature +from proteus.mprans import cArgumentsDict +from proteus.LinearAlgebraTools import SparseMat +from proteus import TimeIntegration +from proteus.NonlinearSolvers import ExplicitLumpedMassMatrixForRichards + +class ThetaScheme(TimeIntegration.BackwardEuler): + def __init__(self,transport,integrateInterpolationPoints=False): + self.transport=transport + TimeIntegration.BackwardEuler.__init__(self,transport, integrateInterpolationPoints) + def updateTimeHistory(self,resetFromDOF=False): + TimeIntegration.BackwardEuler.updateTimeHistory(self,resetFromDOF) + self.transport.u_dof_old[:] = self.u +class RKEV(TimeIntegration.SSP): + from proteus import TimeIntegration + """ + Wrapper for SSPRK time integration using EV + + ... more to come ... + """ + + def __init__(self, transport, timeOrder=1, runCFL=0.1, integrateInterpolationPoints=False): + TimeIntegration.SSP.__init__(self, transport, integrateInterpolationPoints=integrateInterpolationPoints) + self.runCFL = runCFL + self.dtLast = None + self.isAdaptive = True + # About the cfl + assert transport.coefficients.STABILIZATION_TYPE > 0, "SSP method just works for edge based EV methods; i.e., STABILIZATION_TYPE>0" + assert hasattr(transport, 'edge_based_cfl'), "No edge based cfl defined" + self.cfl = transport.edge_based_cfl + # Stuff particular for SSP + self.timeOrder = timeOrder # order of approximation + self.nStages = timeOrder # number of stages total + self.lstage = 0 # last stage completed + # storage vectors + self.u_dof_last = {} + # per component stage values, list with array at each stage + self.u_dof_stage = {} + for ci in range(self.nc): + if ('m', ci) in transport.q: + self.u_dof_last[ci] = transport.u[ci].dof.copy() + self.u_dof_stage[ci] = [] + for k in range(self.nStages + 1): + self.u_dof_stage[ci].append(transport.u[ci].dof.copy()) + + # def set_dt(self, DTSET): + # self.dt = DTSET # don't update t + def choose_dt(self): + comm = Comm.get() + maxCFL = 1.0e-6 + maxCFL = max(maxCFL, comm.globalMax(self.cfl.max())) + self.dt = old_div(self.runCFL, maxCFL) + if self.dtLast is None: + self.dtLast = self.dt + self.t = self.tLast + self.dt + self.substeps = [self.t for i in range(self.nStages)] # Manuel is ignoring different time step levels for now + + def initialize_dt(self, t0, tOut, q): + """ + Modify self.dt + """ + self.tLast = t0 + self.choose_dt() + self.t = t0 + self.dt + + def setCoefficients(self): + """ + beta are all 1's here + mwf not used right now + """ + self.alpha = np.zeros((self.nStages, self.nStages), 'd') + self.dcoefs = np.zeros((self.nStages), 'd') + + def updateStage(self): + """ + Need to switch to use coefficients + """ + self.lstage += 1 + assert self.timeOrder in [1, 2, 3] + assert self.lstage > 0 and self.lstage <= self.timeOrder + if self.timeOrder == 3: + if self.lstage == 1: + logEvent("First stage of SSP33 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + # update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] + elif self.lstage == 2: + logEvent("Second stage of SSP33 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + self.u_dof_stage[ci][self.lstage] *= old_div(1., 4.) + self.u_dof_stage[ci][self.lstage] += 3. / 4. * self.u_dof_last[ci] + # Update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] + elif self.lstage == 3: + logEvent("Third stage of SSP33 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + self.u_dof_stage[ci][self.lstage] *= old_div(2.0, 3.0) + self.u_dof_stage[ci][self.lstage] += 1.0 / 3.0 * self.u_dof_last[ci] + # update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_last[ci] + # update solution to u[0].dof + self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] + elif self.timeOrder == 2: + if self.lstage == 1: + logEvent("First stage of SSP22 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + # Update u_dof_old + self.transport.u_dof_old[:] = self.transport.u[ci].dof + elif self.lstage == 2: + logEvent("Second stage of SSP22 method", level=4) + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof + self.u_dof_stage[ci][self.lstage][:] *= old_div(1., 2.) + self.u_dof_stage[ci][self.lstage][:] += 1. / 2. * self.u_dof_last[ci] + # update u_dof_old + self.transport.u_dof_old[:] = self.u_dof_last[ci] + # update solution to u[0].dof + self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] + else: + assert self.timeOrder == 1 + for ci in range(self.nc): + self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof[:] + self.transport.u_dof_old[:] = self.transport.u[ci].dof + + def initializeTimeHistory(self, resetFromDOF=True): + """ + Push necessary information into time history arrays + """ + for ci in range(self.nc): + self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] + for k in range(self.nStages): + self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] + + def updateTimeHistory(self, resetFromDOF=False): + """ + assumes successful step has been taken + """ + + self.t = self.tLast + self.dt + for ci in range(self.nc): + self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] + for k in range(self.nStages): + self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] + self.lstage = 0 + self.dtLast = self.dt + self.tLast = self.t + + def generateSubsteps(self, tList): + """ + create list of substeps over time values given in tList. These correspond to stages + """ + self.substeps = [] + tLast = self.tLast + for t in tList: + dttmp = t - tLast + self.substeps.extend([tLast + dttmp for i in range(self.nStages)]) + tLast = t + + def resetOrder(self, order): + """ + initialize data structures for stage updges + """ + self.timeOrder = order # order of approximation + self.nStages = order # number of stages total + self.lstage = 0 # last stage completed + # storage vectors + # per component stage values, list with array at each stage + self.u_dof_stage = {} + for ci in range(self.nc): + if ('m', ci) in self.transport.q: + self.u_dof_stage[ci] = [] + for k in range(self.nStages + 1): + self.u_dof_stage[ci].append(self.transport.u[ci].dof.copy()) + self.substeps = [self.t for i in range(self.nStages)] + + def setFromOptions(self, nOptions): + """ + allow classes to set various numerical parameters + """ + if 'runCFL' in dir(nOptions): + self.runCFL = nOptions.runCFL + flags = ['timeOrder'] + for flag in flags: + if flag in dir(nOptions): + val = getattr(nOptions, flag) + setattr(self, flag, val) + if flag == 'timeOrder': + self.resetOrder(self.timeOrder) + +class Coefficients(proteus.TransportCoefficients.TC_base): + """ + version of Re where element material type id's used in evals + """ + from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2 + from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchten_sd_het + def __init__(self, + nd, + Ksw_types, + vgm_n_types, + vgm_alpha_types, + thetaR_types, + thetaSR_types, + gravity, + density, + beta, + diagonal_conductivity=True, + getSeepageFace=None, + # FOR EDGE BASED EV + STABILIZATION_TYPE=0, + ENTROPY_TYPE=2, # logarithmic + LUMPED_MASS_MATRIX=False, + MONOLITHIC=True, + FCT=False, + forceStrongBoundaryConditions=False, + num_fct_iter=1, + # FOR ENTROPY VISCOSITY + cE=1.0, + uL=0.0, + uR=1.0, + # FOR ARTIFICIAL COMPRESSION + cK=1.0, + # OUTPUT quantDOFs + outputQuantDOFs=False): + variableNames=['pressure_head'] + nc=1 + mass={0:{0:'nonlinear'}} + advection={0:{0:'nonlinear'}} + diffusion={0:{0:{0:'nonlinear'}}} + potential={0:{0:'u'}} + reaction={0:{0:'linear'}} + hamiltonian={} + self.getSeepageFace=getSeepageFace + self.gravity=gravity + self.rho = density + self.beta=beta + self.vgm_n_types = vgm_n_types + self.vgm_alpha_types = vgm_alpha_types + self.thetaR_types = thetaR_types + self.thetaSR_types = thetaSR_types + self.elementMaterialTypes = None + self.exteriorElementBoundaryTypes = None + self.materialTypes_q = None + self.materialTypes_ebq = None + self.materialTypes_ebqe = None + self.nd = nd + self.nMaterialTypes = len(thetaR_types) + self.q = {}; self.ebqe = {}; self.ebq = {}; self.ebq_global={} + #try to allow some flexibility in input of permeability/conductivity tensor + self.diagonal_conductivity = diagonal_conductivity + self.Ksw_types_in = Ksw_types + if self.diagonal_conductivity: + sparseDiffusionTensors = {(0,0):(np.arange(self.nd+1,dtype='i'), + np.arange(self.nd,dtype='i'))} + + assert len(Ksw_types.shape) in [1,2], "if diagonal conductivity true then Ksw_types scalar or vector of diagonal entries" + #allow scalar input Ks + if len(Ksw_types.shape)==1: + self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd),'d') + for I in range(self.nd): + self.Ksw_types[:,I] = Ksw_types + else: + self.Ksw_types = Ksw_types + else: #full + sparseDiffusionTensors = {(0,0):(np.arange(self.nd**2+1,step=self.nd,dtype='i'), + np.array([list(range(self.nd)) for row in range(self.nd)],dtype='i'))} + assert len(Ksw_types.shape) in [1,2], "if full tensor conductivity true then Ksw_types scalar or 'flattened' row-major representation of entries" + if len(Ksw_types.shape)==1: + self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd**2),'d') + for I in range(self.nd): + self.Ksw_types[:,I*self.nd+I] = Ksw_types + else: + assert Ksw_types.shape[1] == self.nd**2 + self.Ksw_types = Ksw_types + # EDGE BASED (AND ENTROPY) VISCOSITY + self.LUMPED_MASS_MATRIX = LUMPED_MASS_MATRIX + self.MONOLITHIC = MONOLITHIC + self.STABILIZATION_TYPE = STABILIZATION_TYPE + self.ENTROPY_TYPE = ENTROPY_TYPE + self.FCT = FCT + self.num_fct_iter=num_fct_iter + self.uL = uL + self.uR = uR + self.cK = cK + self.forceStrongConditions = forceStrongBoundaryConditions + self.cE = cE + self.outputQuantDOFs = outputQuantDOFs + TC_base.__init__(self, + nc, + mass, + advection, + diffusion, + potential, + reaction, + hamiltonian, + variableNames, + sparseDiffusionTensors = sparseDiffusionTensors, + useSparseDiffusion = True) + + def initializeMesh(self,mesh): + from proteus.SubsurfaceTransportCoefficients import BlockHeterogeneousCoefficients + self.elementMaterialTypes,self.exteriorElementBoundaryTypes,self.elementBoundaryTypes = BlockHeterogeneousCoefficients(mesh).initializeMaterialTypes() + #want element boundary material types for evaluating heterogeneity + #not boundary conditions + self.isSeepageFace = np.zeros((mesh.nExteriorElementBoundaries_global),'i') + if self.getSeepageFace != None: + for ebNE in range(mesh.nExteriorElementBoundaries_global): + #mwf missing ebNE-->ebN? + ebN = mesh.exteriorElementBoundariesArray[ebNE] + #print "eb flag",mesh.elementBoundaryMaterialTypes[ebN] + #print self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) + self.isSeepageFace[ebNE] = self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) + #print self.isSeepageFace + def initializeElementQuadrature(self,t,cq): + self.materialTypes_q = self.elementMaterialTypes + self.q_shape = cq[('u',0)].shape +# cq['Ks'] = np.zeros(self.q_shape,'d') +# for k in range(self.q_shape[1]): +# cq['Ks'][:,k] = self.Ksw_types[self.elementMaterialTypes,0] + self.q[('vol_frac',0)] = np.zeros(self.q_shape,'d') + def initializeElementBoundaryQuadrature(self,t,cebq,cebq_global): + self.materialTypes_ebq = np.zeros(cebq[('u',0)].shape[0:2],'i') + self.ebq_shape = cebq[('u',0)].shape + for ebN_local in range(self.ebq_shape[1]): + self.materialTypes_ebq[:,ebN_local] = self.elementMaterialTypes + self.ebq[('vol_frac',0)] = np.zeros(self.ebq_shape,'d') + + def initializeGlobalExteriorElementBoundaryQuadrature(self,t,cebqe): + self.materialTypes_ebqe = self.exteriorElementBoundaryTypes + self.ebqe_shape = cebqe[('u',0)].shape + self.ebqe[('vol_frac',0)] = np.zeros(self.ebqe_shape,'d') + # + def evaluate(self,t,c): + if c[('u',0)].shape == self.q_shape: + materialTypes = self.materialTypes_q + vol_frac = self.q[('vol_frac',0)] + elif c[('u',0)].shape == self.ebqe_shape: + materialTypes = self.materialTypes_ebqe + vol_frac = self.ebqe[('vol_frac',0)] + elif c[('u',0)].shape == self.ebq_shape: + materialTypes = self.materialTypes_ebq + vol_frac = self.ebq[('vol_frac',0)] + else: + assert False, "no materialType found to match c[('u',0)].shape= %s " % c[('u',0)].shape + self.conservativeHeadRichardsMualemVanGenuchten_sd_het(self.sdInfo[(0,0)][0], + self.sdInfo[(0,0)][1], + materialTypes, + self.rho, + self.beta, + self.gravity, + self.vgm_alpha_types, + self.vgm_n_types, + self.thetaR_types, + self.thetaSR_types, + self.Ksw_types, + c[('u',0)], + c[('m',0)], + c[('dm',0,0)], + c[('f',0)], + c[('df',0,0)], + c[('a',0,0)], + c[('da',0,0,0)], + vol_frac) + # print "Picard---------------------------------------------------------------" + # c[('df',0,0)][:] = 0.0 + # c[('da',0,0,0)][:] = 0.0 +# self.conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2(materialTypes, +# self.rho, +# self.beta, +# self.gravity, +# self.vgm_alpha_types, +# self.vgm_n_types, +# self.thetaR_types, +# self.thetaSR_types, +# self.Ksw_types, +# c[('u',0)], +# c[('m',0)], +# c[('dm',0,0)], +# c[('f',0)], +# c[('df',0,0)], +# c[('a',0,0)], +# c[('da',0,0,0)]) + #mwf debug + if (np.isnan(c[('da',0,0,0)]).any() or + np.isnan(c[('a',0,0)]).any() or + np.isnan(c[('df',0,0)]).any() or + np.isnan(c[('f',0)]).any() or + np.isnan(c[('u',0)]).any() or + np.isnan(c[('m',0)]).any() or + np.isnan(c[('dm',0,0)]).any()): + import pdb + pdb.set_trace() + +# #mwf debug +# if c[('u',0)].shape == self.q_shape: +# c[('visPerm',0)]=c[('a',0,0)][:,:,0,0] + +class LevelModel(proteus.Transport.OneLevelTransport): + nCalls=0 + def __init__(self, + uDict, + phiDict, + testSpaceDict, + matType, + dofBoundaryConditionsDict, + dofBoundaryConditionsSetterDict, + coefficients, + elementQuadrature, + elementBoundaryQuadrature, + fluxBoundaryConditionsDict=None, + advectiveFluxBoundaryConditionsSetterDict=None, + diffusiveFluxBoundaryConditionsSetterDictDict=None, + stressTraceBoundaryConditionsSetterDict=None, + stabilization=None, + shockCapturing=None, + conservativeFluxDict=None, + numericalFluxType=None, + TimeIntegrationClass=None, + massLumping=False, + reactionLumping=False, + options=None, + name='defaultName', + reuse_trial_and_test_quadrature=True, + sd = True, + movingDomain=False, + bdyNullSpace=False): + self.bdyNullSpace=bdyNullSpace + # + #set the objects describing the method and boundary conditions + # + self.movingDomain=movingDomain + self.tLast_mesh=None + # + self.name=name + self.sd=sd + self.Hess=False + self.lowmem=True + self.timeTerm=True#allow turning off the time derivative + #self.lowmem=False + self.testIsTrial=True + self.phiTrialIsTrial=True + self.u = uDict + self.ua = {}#analytical solutions + self.phi = phiDict + self.dphi={} + self.matType = matType + #mwf try to reuse test and trial information across components if spaces are the same + self.reuse_test_trial_quadrature = reuse_trial_and_test_quadrature#True#False + if self.reuse_test_trial_quadrature: + for ci in range(1,coefficients.nc): + assert self.u[ci].femSpace.__class__.__name__ == self.u[0].femSpace.__class__.__name__, "to reuse_test_trial_quad all femSpaces must be the same!" + self.u_dof_old = None + ## Simplicial Mesh + self.mesh = self.u[0].femSpace.mesh #assume the same mesh for all components for now + self.testSpace = testSpaceDict + self.dirichletConditions = dofBoundaryConditionsDict + self.dirichletNodeSetList=None #explicit Dirichlet conditions for now, no Dirichlet BC constraints + self.coefficients = coefficients + self.coefficients.initializeMesh(self.mesh) + self.nc = self.coefficients.nc + self.stabilization = stabilization + self.shockCapturing = shockCapturing + self.conservativeFlux = conservativeFluxDict #no velocity post-processing for now + self.fluxBoundaryConditions=fluxBoundaryConditionsDict + self.advectiveFluxBoundaryConditionsSetterDict=advectiveFluxBoundaryConditionsSetterDict + self.diffusiveFluxBoundaryConditionsSetterDictDict = diffusiveFluxBoundaryConditionsSetterDictDict + #determine whether the stabilization term is nonlinear + self.stabilizationIsNonlinear = False + #cek come back + if self.stabilization != None: + for ci in range(self.nc): + if ci in coefficients.mass: + for flag in list(coefficients.mass[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.advection: + for flag in list(coefficients.advection[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.diffusion: + for diffusionDict in list(coefficients.diffusion[ci].values()): + for flag in list(diffusionDict.values()): + if flag != 'constant': + self.stabilizationIsNonlinear=True + if ci in coefficients.potential: + for flag in list(coefficients.potential[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.reaction: + for flag in list(coefficients.reaction[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + if ci in coefficients.hamiltonian: + for flag in list(coefficients.hamiltonian[ci].values()): + if flag == 'nonlinear': + self.stabilizationIsNonlinear=True + #determine if we need element boundary storage + self.elementBoundaryIntegrals = {} + for ci in range(self.nc): + self.elementBoundaryIntegrals[ci] = ((self.conservativeFlux != None) or + (numericalFluxType != None) or + (self.fluxBoundaryConditions[ci] == 'outFlow') or + (self.fluxBoundaryConditions[ci] == 'mixedFlow') or + (self.fluxBoundaryConditions[ci] == 'setFlow')) + # + #calculate some dimensions + # + self.nSpace_global = self.u[0].femSpace.nSpace_global #assume same space dim for all variables + self.nDOF_trial_element = [u_j.femSpace.max_nDOF_element for u_j in list(self.u.values())] + self.nDOF_phi_trial_element = [phi_k.femSpace.max_nDOF_element for phi_k in list(self.phi.values())] + self.n_phi_ip_element = [phi_k.femSpace.referenceFiniteElement.interpolationConditions.nQuadraturePoints for phi_k in list(self.phi.values())] + self.nDOF_test_element = [femSpace.max_nDOF_element for femSpace in list(self.testSpace.values())] + self.nFreeDOF_global = [dc.nFreeDOF_global for dc in list(self.dirichletConditions.values())] + self.nVDOF_element = sum(self.nDOF_trial_element) + self.nFreeVDOF_global = sum(self.nFreeDOF_global) + # + NonlinearEquation.__init__(self,self.nFreeVDOF_global) + # + #build the quadrature point dictionaries from the input (this + #is just for convenience so that the input doesn't have to be + #complete) + # + elementQuadratureDict={} + elemQuadIsDict = isinstance(elementQuadrature,dict) + if elemQuadIsDict: #set terms manually + for I in self.coefficients.elementIntegralKeys: + if I in elementQuadrature: + elementQuadratureDict[I] = elementQuadrature[I] + else: + elementQuadratureDict[I] = elementQuadrature['default'] + else: + for I in self.coefficients.elementIntegralKeys: + elementQuadratureDict[I] = elementQuadrature + if self.stabilization != None: + for I in self.coefficients.elementIntegralKeys: + if elemQuadIsDict: + if I in elementQuadrature: + elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature[I] + else: + elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature['default'] + else: + elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature + if self.shockCapturing != None: + for ci in self.shockCapturing.components: + if elemQuadIsDict: + if ('numDiff',ci,ci) in elementQuadrature: + elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature[('numDiff',ci,ci)] + else: + elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature['default'] + else: + elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature + if massLumping: + for ci in list(self.coefficients.mass.keys()): + elementQuadratureDict[('m',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + for I in self.coefficients.elementIntegralKeys: + elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + if reactionLumping: + for ci in list(self.coefficients.mass.keys()): + elementQuadratureDict[('r',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + for I in self.coefficients.elementIntegralKeys: + elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + elementBoundaryQuadratureDict={} + if isinstance(elementBoundaryQuadrature,dict): #set terms manually + for I in self.coefficients.elementBoundaryIntegralKeys: + if I in elementBoundaryQuadrature: + elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature[I] + else: + elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature['default'] + else: + for I in self.coefficients.elementBoundaryIntegralKeys: + elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature + # + # find the union of all element quadrature points and + # build a quadrature rule for each integral that has a + # weight at each point in the union + #mwf include tag telling me which indices are which quadrature rule? + (self.elementQuadraturePoints,self.elementQuadratureWeights, + self.elementQuadratureRuleIndeces) = Quadrature.buildUnion(elementQuadratureDict) + self.nQuadraturePoints_element = self.elementQuadraturePoints.shape[0] + self.nQuadraturePoints_global = self.nQuadraturePoints_element*self.mesh.nElements_global + # + #Repeat the same thing for the element boundary quadrature + # + (self.elementBoundaryQuadraturePoints, + self.elementBoundaryQuadratureWeights, + self.elementBoundaryQuadratureRuleIndeces) = Quadrature.buildUnion(elementBoundaryQuadratureDict) + self.nElementBoundaryQuadraturePoints_elementBoundary = self.elementBoundaryQuadraturePoints.shape[0] + self.nElementBoundaryQuadraturePoints_global = (self.mesh.nElements_global* + self.mesh.nElementBoundaries_element* + self.nElementBoundaryQuadraturePoints_elementBoundary) +# if isinstance(self.u[0].femSpace,C0_AffineLinearOnSimplexWithNodalBasis): +# print self.nQuadraturePoints_element +# if self.nSpace_global == 3: +# assert(self.nQuadraturePoints_element == 5) +# elif self.nSpace_global == 2: +# assert(self.nQuadraturePoints_element == 6) +# elif self.nSpace_global == 1: +# assert(self.nQuadraturePoints_element == 3) +# +# print self.nElementBoundaryQuadraturePoints_elementBoundary +# if self.nSpace_global == 3: +# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) +# elif self.nSpace_global == 2: +# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) +# elif self.nSpace_global == 1: +# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 1) + + # + #storage dictionaries + self.scalars_element = set() + # + #simplified allocations for test==trial and also check if space is mixed or not + # + self.q={} + self.ebq={} + self.ebq_global={} + self.ebqe={} + self.phi_ip={} + self.edge_based_cfl = np.zeros(self.u[0].dof.shape)+100 + #mesh + #self.q['x'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,3),'d') + self.q[('dV_u', 0)] = (old_div(1.0, self.mesh.nElements_global)) * np.ones((self.mesh.nElements_global, self.nQuadraturePoints_element), 'd') + self.ebqe['x'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,3),'d') + self.q[('u',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') + self.q[('grad(u)',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') + self.q['velocity'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') + self.q[('m',0)] = self.q[('u',0)].copy() + self.q[('mt',0)] = self.q[('u',0)].copy() + self.q[('m_last',0)] = self.q[('u',0)].copy() + self.q[('m_tmp',0)] = self.q[('u',0)].copy() + self.q[('cfl',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') + self.q[('numDiff',0,0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') + self.ebqe[('u',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.ebqe[('grad(u)',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') + self.ebqe['velocity'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') + self.ebqe[('advectiveFlux_bc_flag',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'i') + self.ebqe[('advectiveFlux_bc',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.ebqe[('advectiveFlux',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.ebqe[('penalty')] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.points_elementBoundaryQuadrature= set() + self.scalars_elementBoundaryQuadrature= set([('u',ci) for ci in range(self.nc)]) + self.vectors_elementBoundaryQuadrature= set() + self.tensors_elementBoundaryQuadrature= set() + self.inflowBoundaryBC = {} + self.inflowBoundaryBC_values = {} + self.inflowFlux = {} + for cj in range(self.nc): + self.inflowBoundaryBC[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,),'i') + self.inflowBoundaryBC_values[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nDOF_trial_element[cj]),'d') + self.inflowFlux[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') + self.internalNodes = set(range(self.mesh.nNodes_global)) + #identify the internal nodes this is ought to be in mesh + ##\todo move this to mesh + for ebNE in range(self.mesh.nExteriorElementBoundaries_global): + ebN = self.mesh.exteriorElementBoundariesArray[ebNE] + eN_global = self.mesh.elementBoundaryElementsArray[ebN,0] + ebN_element = self.mesh.elementBoundaryLocalElementBoundariesArray[ebN,0] + for i in range(self.mesh.nNodes_element): + if i != ebN_element: + I = self.mesh.elementNodesArray[eN_global,i] + self.internalNodes -= set([I]) + self.nNodes_internal = len(self.internalNodes) + self.internalNodesArray=np.zeros((self.nNodes_internal,),'i') + for nI,n in enumerate(self.internalNodes): + self.internalNodesArray[nI]=n + # + del self.internalNodes + self.internalNodes = None + logEvent("Updating local to global mappings",2) + self.updateLocal2Global() + logEvent("Building time integration object",2) + logEvent(memory("inflowBC, internalNodes,updateLocal2Global","OneLevelTransport"),level=4) + #mwf for interpolating subgrid error for gradients etc + if self.stabilization and self.stabilization.usesGradientStabilization: + self.timeIntegration = TimeIntegrationClass(self,integrateInterpolationPoints=True) + else: + self.timeIntegration = TimeIntegrationClass(self) + + if options != None: + self.timeIntegration.setFromOptions(options) + logEvent(memory("TimeIntegration","OneLevelTransport"),level=4) + logEvent("Calculating numerical quadrature formulas",2) + self.calculateQuadrature() + #lay out components/equations contiguously for now + self.offset = [0] + for ci in range(1,self.nc): + self.offset += [self.offset[ci-1]+self.nFreeDOF_global[ci-1]] + self.stride = [1 for ci in range(self.nc)] + #use contiguous layout of components for parallel, requires weak DBC's + # mql. Some ASSERTS to restrict the combination of the methods + if self.coefficients.STABILIZATION_TYPE > 0: + pass + #assert self.timeIntegration.isSSP == True, "If STABILIZATION_TYPE>0, use RKEV timeIntegration within VOF model" + #cond = 'levelNonlinearSolver' in dir(options) and (options.levelNonlinearSolver == + # ExplicitLumpedMassMatrixForRichards or options.levelNonlinearSolver == ExplicitConsistentMassMatrixForRichards) + #assert cond, "If STABILIZATION_TYPE>0, use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards or ExplicitConsistentMassMatrixForRichards" + try: + if 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards: + assert self.coefficients.LUMPED_MASS_MATRIX, "If levelNonlinearSolver=ExplicitLumpedMassMatrix, use LUMPED_MASS_MATRIX=True" + except: + pass + if self.coefficients.LUMPED_MASS_MATRIX == True: + cond = self.coefficients.STABILIZATION_TYPE == 2 + assert cond, "Use lumped mass matrix just with: STABILIZATION_TYPE=2 (smoothness based stab.)" + cond = 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards + assert cond, "Use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards when the mass matrix is lumped" + if self.coefficients.FCT == True: + cond = self.coefficients.STABILIZATION_TYPE > 0, "Use FCT just with STABILIZATION_TYPE>0; i.e., edge based stabilization" + # END OF ASSERTS + + # cek adding empty data member for low order numerical viscosity structures here for now + self.ML = None # lumped mass matrix + self.MC_global = None # consistent mass matrix + self.cterm_global = None + self.cterm_transpose_global = None + # dL_global and dC_global are not the full matrices but just the CSR arrays containing the non zero entries + self.residualComputed=False #TMP + self.dLow= None + self.fluxMatrix = None + self.uDotLow = None + self.uLow = None + self.dt_times_dC_minus_dL = None + self.min_s_bc = None + self.max_s_bc = None + # Aux quantity at DOFs to be filled by optimized code (MQL) + self.quantDOFs = np.zeros(self.u[0].dof.shape, 'd') + self.sLow = np.zeros(self.u[0].dof.shape, 'd') + self.sHigh = np.zeros(self.u[0].dof.shape, 'd') + self.sn = np.zeros(self.u[0].dof.shape, 'd') + comm = Comm.get() + self.comm=comm + if comm.size() > 1: + assert numericalFluxType != None and numericalFluxType.useWeakDirichletConditions,"You must use a numerical flux to apply weak boundary conditions for parallel runs" + self.offset = [0] + for ci in range(1,self.nc): + self.offset += [ci] + self.stride = [self.nc for ci in range(self.nc)] + # + logEvent(memory("stride+offset","OneLevelTransport"),level=4) + if numericalFluxType != None: + if options is None or options.periodicDirichletConditions is None: + self.numericalFlux = numericalFluxType(self, + dofBoundaryConditionsSetterDict, + advectiveFluxBoundaryConditionsSetterDict, + diffusiveFluxBoundaryConditionsSetterDictDict) + else: + self.numericalFlux = numericalFluxType(self, + dofBoundaryConditionsSetterDict, + advectiveFluxBoundaryConditionsSetterDict, + diffusiveFluxBoundaryConditionsSetterDictDict, + options.periodicDirichletConditions) + else: + self.numericalFlux = None + #set penalty terms + #cek todo move into numerical flux initialization + if 'penalty' in self.ebq_global: + for ebN in range(self.mesh.nElementBoundaries_global): + for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): + self.ebq_global['penalty'][ebN,k] = old_div(self.numericalFlux.penalty_constant,(self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power)) + #penalty term + #cek move to Numerical flux initialization + if 'penalty' in self.ebqe: + for ebNE in range(self.mesh.nExteriorElementBoundaries_global): + ebN = self.mesh.exteriorElementBoundariesArray[ebNE] + for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): + self.ebqe['penalty'][ebNE,k] = old_div(self.numericalFlux.penalty_constant,self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power) + logEvent(memory("numericalFlux","OneLevelTransport"),level=4) + self.elementEffectiveDiametersArray = self.mesh.elementInnerDiametersArray + #use post processing tools to get conservative fluxes, None by default + from proteus import PostProcessingTools + self.velocityPostProcessor = PostProcessingTools.VelocityPostProcessingChooser(self) + logEvent(memory("velocity postprocessor","OneLevelTransport"),level=4) + #helper for writing out data storage + from proteus import Archiver + self.elementQuadratureDictionaryWriter = Archiver.XdmfWriter() + self.elementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() + self.exteriorElementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() + #TODO get rid of this + for ci,fbcObject in list(self.fluxBoundaryConditionsObjectsDict.items()): + self.ebqe[('advectiveFlux_bc_flag',ci)] = np.zeros(self.ebqe[('advectiveFlux_bc',ci)].shape,'i') + for t,g in list(fbcObject.advectiveFluxBoundaryConditionsDict.items()): + if ci in self.coefficients.advection: + self.ebqe[('advectiveFlux_bc',ci)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) + self.ebqe[('advectiveFlux_bc_flag',ci)][t[0],t[1]] = 1 + + if hasattr(self.numericalFlux,'setDirichletValues'): + self.numericalFlux.setDirichletValues(self.ebqe) + if not hasattr(self.numericalFlux,'isDOFBoundary'): + self.numericalFlux.isDOFBoundary = {0:np.zeros(self.ebqe[('u',0)].shape,'i')} + if not hasattr(self.numericalFlux,'ebqe'): + self.numericalFlux.ebqe = {('u',0):np.zeros(self.ebqe[('u',0)].shape,'d')} + #TODO how to handle redistancing calls for calculateCoefficients,calculateElementResidual etc + self.globalResidualDummy = None + compKernelFlag=0 + self.delta_x_ij=None + self.richards = cRichards_base(self.nSpace_global, + self.nQuadraturePoints_element, + self.u[0].femSpace.elementMaps.localFunctionSpace.dim, + self.u[0].femSpace.referenceFiniteElement.localFunctionSpace.dim, + self.testSpace[0].referenceFiniteElement.localFunctionSpace.dim, + self.nElementBoundaryQuadraturePoints_elementBoundary, + compKernelFlag) + if self.movingDomain: + self.MOVING_DOMAIN=1.0 + else: + self.MOVING_DOMAIN=0.0 + #cek hack + self.movingDomain=False + self.MOVING_DOMAIN=0.0 + if self.mesh.nodeVelocityArray is None: + self.mesh.nodeVelocityArray = np.zeros(self.mesh.nodeArray.shape,'d') + self.forceStrongConditions=self.coefficients.forceStrongConditions + self.dirichletConditionsForceDOF = {} + if self.forceStrongConditions: + for cj in range(self.nc): + self.dirichletConditionsForceDOF[cj] = DOFBoundaryConditions(self.u[cj].femSpace,dofBoundaryConditionsSetterDict[cj],weakDirichletConditions=False) + def FCTStep(self): + import pdb + rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() + limited_solution = np.zeros((len(rowptr) - 1),'d') + #self.u_free_dof_stage_0_l = np.zeros((len(rowptr) - 1),'d') + #self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage], # soln + #fromFreeToGlobal=0 + #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + # self.offset[0], + # self.stride[0], + # self.dirichletConditions[0].global2freeGlobal_global_dofs, + # self.dirichletConditions[0].global2freeGlobal_free_dofs, + # self.u_free_dof_stage_0_l, + # self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage]) + argsDict = cArgumentsDict.ArgumentsDict() + argsDict["bc_mask"] = self.bc_mask + argsDict["NNZ"] = self.nnz + argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs + argsDict["dt"] = self.timeIntegration.dt + argsDict["lumped_mass_matrix"] = self.ML + argsDict["soln"] = self.sn + argsDict["pn"] = self.u[0].dof + argsDict["solH"] = self.sHigh + argsDict["uLow"] = self.sLow + argsDict["uDotLow"] = self.uDotLow + argsDict["limited_solution"] = limited_solution + argsDict["csrRowIndeces_DofLoops"] = rowptr + argsDict["csrColumnOffsets_DofLoops"] = colind + argsDict["MassMatrix"] = MassMatrix + argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL + argsDict["min_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0]) #cek hack just set from physical bounds + argsDict["max_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0] + self.coefficients.thetaSR_types[0]) #cek hack + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["MONOLITHIC"] =0#cek hack self.coefficients.MONOLITHIC + #pdb.set_trace() + self.richards.FCTStep(argsDict) + + # self.nnz, # number of non zero entries + # len(rowptr) - 1, # number of DOFs + # self.timeIntegration.dt, + # self.ML, # Lumped mass matrix + # self.sn, + # self.u_dof_old, + # self.sHigh, # high order solution + # self.sLow, + # limited_solution, + # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) + # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) + # MassMatrix, + # self.dt_times_dC_minus_dL, + # self.min_s_bc, + # self.max_s_bc, + # self.coefficients.LUMPED_MASS_MATRIX, + # self.coefficients.MONOLITHIC) + old_dof = self.u[0].dof.copy() + self.invert(limited_solution, self.u[0].dof) + self.timeIntegration.u[:] = self.u[0].dof + #fromFreeToGlobal=1 #direction copying + #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + # self.offset[0], + # self.stride[0], + # self.dirichletConditions[0].global2freeGlobal_global_dofs, + # self.dirichletConditions[0].global2freeGlobal_free_dofs, + # self.u[0].dof, + # limited_solution) + def kth_FCT_step(self): + #import pdb + #pdb.set_trace() + rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() + limitedFlux = np.zeros(self.nnz) + limited_solution = np.zeros((len(rowptr) - 1),'d') + #limited_solution[:] = self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage] + fromFreeToGlobal=0 #direction copying + cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + self.offset[0], + self.stride[0], + self.dirichletConditions[0].global2freeGlobal_global_dofs, + self.dirichletConditions[0].global2freeGlobal_free_dofs, + limited_solution, + self.timeintegration.u_dof_stage[0][self.timeIntegration.lstage]) + + self.richards.kth_FCT_step( + self.timeIntegration.dt, + self.coefficients.num_fct_iter, + self.nnz, # number of non zero entries + len(rowptr) - 1, # number of DOFs + MassMatrix, + self.ML, # Lumped mass matrix + self.u_dof_old, + limited_solution, + self.uDotLow, + self.uLow, + self.dLow, + self.fluxMatrix, + limitedFlux, + rowptr, + colind) + + self.timeIntegration.u[:] = limited_solution + #self.u[0].dof[:] = limited_solution + fromFreeToGlobal=1 #direction copying + cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, + self.offset[0], + self.stride[0], + self.dirichletConditions[0].global2freeGlobal_global_dofs, + self.dirichletConditions[0].global2freeGlobal_free_dofs, + self.u[0].dof, + limited_solution) + def calculateCoefficients(self): + pass + def calculateElementResidual(self): + if self.globalResidualDummy != None: + self.getResidual(self.u[0].dof,self.globalResidualDummy) + def getResidual(self,u,r): + import pdb + import copy + """ + Calculate the element residuals and add in to the global residual + """ + cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, + self.jacobian) + if self.u_dof_old is None: + # Pass initial condition to u_dof_old + self.u_dof_old = np.copy(self.u[0].dof) + rowptr, colind, nzval = self.jacobian.getCSRrepresentation() + nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix + r.fill(0.0) + ######################## + ### COMPUTE C MATRIX ### + ######################## + if self.cterm_global is None: + # since we only need cterm_global to persist, we can drop the other self.'s + self.cterm = {} + self.cterm_a = {} + self.cterm_global = {} + self.cterm_transpose = {} + self.cterm_a_transpose = {} + self.cterm_global_transpose = {} + rowptr, colind, nzval = self.jacobian.getCSRrepresentation() + nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix + di = self.q[('grad(u)', 0)].copy() # direction of derivative + # JACOBIANS (FOR ELEMENT TRANSFORMATION) + self.q[('J')] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nSpace_global, + self.nSpace_global), + 'd') + self.q[('inverse(J)')] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nSpace_global, + self.nSpace_global), + 'd') + self.q[('det(J)')] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element), + 'd') + self.u[0].femSpace.elementMaps.getJacobianValues(self.elementQuadraturePoints, + self.q['J'], + self.q['inverse(J)'], + self.q['det(J)']) + self.q['abs(det(J))'] = np.abs(self.q['det(J)']) + # SHAPE FUNCTIONS + self.q[('w', 0)] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nDOF_test_element[0]), + 'd') + self.q[('w*dV_m', 0)] = self.q[('w', 0)].copy() + self.u[0].femSpace.getBasisValues(self.elementQuadraturePoints, self.q[('w', 0)]) + cfemIntegrals.calculateWeightedShape(self.elementQuadratureWeights[('u', 0)], + self.q['abs(det(J))'], + self.q[('w', 0)], + self.q[('w*dV_m', 0)]) + # GRADIENT OF TEST FUNCTIONS + self.q[('grad(w)', 0)] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nDOF_test_element[0], + self.nSpace_global), + 'd') + self.u[0].femSpace.getBasisGradientValues(self.elementQuadraturePoints, + self.q['inverse(J)'], + self.q[('grad(w)', 0)]) + self.q[('grad(w)*dV_f', 0)] = np.zeros((self.mesh.nElements_global, + self.nQuadraturePoints_element, + self.nDOF_test_element[0], + self.nSpace_global), + 'd') + cfemIntegrals.calculateWeightedShapeGradients(self.elementQuadratureWeights[('u', 0)], + self.q['abs(det(J))'], + self.q[('grad(w)', 0)], + self.q[('grad(w)*dV_f', 0)]) + ########################## + ### LUMPED MASS MATRIX ### + ########################## + # assume a linear mass term + dm = np.ones(self.q[('u', 0)].shape, 'd') + elementMassMatrix = np.zeros((self.mesh.nElements_global, + self.nDOF_test_element[0], + self.nDOF_trial_element[0]), 'd') + cfemIntegrals.updateMassJacobian_weak_lowmem(dm, + self.q[('w', 0)], + self.q[('w*dV_m', 0)], + elementMassMatrix) + self.MC_a = nzval.copy() + self.MC_global = SparseMat(self.nFreeDOF_global[0], + self.nFreeDOF_global[0], + nnz, + self.MC_a, + colind, + rowptr) + cfemIntegrals.zeroJacobian_CSR(self.nnz, self.MC_global) + cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.csrRowIndeces[(0, 0)], + self.csrColumnOffsets[(0, 0)], + elementMassMatrix, + self.MC_global) + self.ML = np.zeros((self.nFreeDOF_global[0],), 'd') + for i in range(self.nFreeDOF_global[0]): + self.ML[i] = self.MC_a[rowptr[i]:rowptr[i + 1]].sum() + np.testing.assert_almost_equal(self.ML.sum(), + self.mesh.volume, + err_msg="Trace of lumped mass matrix should be the domain volume", verbose=True) + for d in range(self.nSpace_global): # spatial dimensions + # C matrices + self.cterm[d] = np.zeros((self.mesh.nElements_global, + self.nDOF_test_element[0], + self.nDOF_trial_element[0]), 'd') + self.cterm_a[d] = nzval.copy() + #self.cterm_a[d] = np.zeros(nzval.size) + self.cterm_global[d] = SparseMat(self.nFreeDOF_global[0], + self.nFreeDOF_global[0], + nnz, + self.cterm_a[d], + colind, + rowptr) + cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global[d]) + di[:] = 0.0 + di[..., d] = 1.0 + cfemIntegrals.updateHamiltonianJacobian_weak_lowmem(di, + self.q[('grad(w)*dV_f', 0)], + self.q[('w', 0)], + self.cterm[d]) # int[(di*grad(wj))*wi*dV] + cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.csrRowIndeces[(0, 0)], + self.csrColumnOffsets[(0, 0)], + self.cterm[d], + self.cterm_global[d]) + # C Transpose matrices + self.cterm_transpose[d] = np.zeros((self.mesh.nElements_global, + self.nDOF_test_element[0], + self.nDOF_trial_element[0]), 'd') + self.cterm_a_transpose[d] = nzval.copy() + self.cterm_global_transpose[d] = SparseMat(self.nFreeDOF_global[0], + self.nFreeDOF_global[0], + nnz, + self.cterm_a_transpose[d], + colind, + rowptr) + cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global_transpose[d]) + di[:] = 0.0 + di[..., d] = -1.0 + cfemIntegrals.updateAdvectionJacobian_weak_lowmem(di, + self.q[('w', 0)], + self.q[('grad(w)*dV_f', 0)], + self.cterm_transpose[d]) # -int[(-di*grad(wi))*wj*dV] + cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.l2g[0]['nFreeDOF'], + self.l2g[0]['freeLocal'], + self.csrRowIndeces[(0, 0)], + self.csrColumnOffsets[(0, 0)], + self.cterm_transpose[d], + self.cterm_global_transpose[d]) + + rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() + else: + Cy = np.zeros(Cx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() + else: + Cz = np.zeros(Cx.shape, 'd') + rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() + else: + CTy = np.zeros(CTx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() + else: + CTz = np.zeros(CTx.shape, 'd') + + # This is dummy. I just care about the csr structure of the sparse matrix + self.dLow = np.zeros(Cx.shape, 'd') + self.fluxMatrix = np.zeros(Cx.shape, 'd') + self.dt_times_dC_minus_dL = np.zeros(Cx.shape, 'd') + nFree = len(rowptr)-1 + self.min_s_bc = np.zeros(nFree, 'd') + 1E10 + self.max_s_bc = np.zeros(nFree, 'd') - 1E10 + self.uDotLow = np.zeros(nFree, 'd') + self.uLow = np.zeros(nFree, 'd') + # + # cek end computationa of cterm_global + # + # cek showing mquezada an example of using cterm_global sparse matrix + # calculation y = c*x where x==1 + # direction=0 + #rowptr, colind, c = self.cterm_global[direction].getCSRrepresentation() + #y = np.zeros((self.nFreeDOF_global[0],),'d') + #x = np.ones((self.nFreeDOF_global[0],),'d') + # ij=0 + # for i in range(self.nFreeDOF_global[0]): + # for offset in range(rowptr[i],rowptr[i+1]): + # j = colind[offset] + # y[i] += c[ij]*x[j] + # ij+=1 + #Load the unknowns into the finite element dof + self.timeIntegration.calculateCoefs() + self.timeIntegration.calculateU(u) + self.setUnknowns(self.timeIntegration.u) + #cek can put in logic to skip of BC's don't depend on t or u + #Dirichlet boundary conditions + self.numericalFlux.setDirichletValues(self.ebqe) + #flux boundary conditions + #cek hack, just using advective flux for flux BC for now + for t,g in list(self.fluxBoundaryConditionsObjectsDict[0].advectiveFluxBoundaryConditionsDict.items()): + self.ebqe[('advectiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) + self.ebqe[('advectiveFlux_bc_flag',0)][t[0],t[1]] = 1 + # for t,g in self.fluxBoundaryConditionsObjectsDict[0].diffusiveFluxBoundaryConditionsDict.iteritems(): + # self.ebqe[('diffusiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) + # self.ebqe[('diffusiveFlux_bc_flag',0)][t[0],t[1]] = 1 + #self.shockCapturing.lag=True + if self.forceStrongConditions: + self.bc_mask = np.ones_like(self.u[0].dof) + for cj in range(len(self.dirichletConditionsForceDOF)): + for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): + self.u[cj].dof[dofN] = g(self.dirichletConditionsForceDOF[cj].DOFBoundaryPointDict[dofN],self.timeIntegration.t) + self.u_dof_old[dofN] = self.u[cj].dof[dofN] + self.bc_mask[dofN] = 0.0 + degree_polynomial = 1 + try: + degree_polynomial = self.u[0].femSpace.order + except: + pass + + argsDict = cArgumentsDict.ArgumentsDict() + if self.forceStrongConditions: + argsDict["bc_mask"] = self.bc_mask + argsDict["dt"] = self.timeIntegration.dt + argsDict["Theta"] = 1.0 + argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi + argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi + argsDict["mesh_dof"] = self.mesh.nodeArray + argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray + argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN + argsDict["mesh_l2g"] = self.mesh.elementNodesArray + argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] + argsDict["u_trial_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi + argsDict["u_test_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi + argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace + argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace + argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] + argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals + argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians + argsDict["nElements_global"] = self.mesh.nElements_global + argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] + argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, + argsDict["isSeepageFace"] = self.coefficients.isSeepageFace + argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] + argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] + argsDict["rho"] = self.coefficients.rho + argsDict["beta"] = self.coefficients.beta + argsDict["gravity"] = self.coefficients.gravity + argsDict["alpha"] = self.coefficients.vgm_alpha_types + argsDict["n"] = self.coefficients.vgm_n_types + argsDict["thetaR"] = self.coefficients.thetaR_types + argsDict["thetaSR"] = self.coefficients.thetaSR_types + argsDict["KWs"] = self.coefficients.Ksw_types + argsDict["useMetrics"] = 0.0 + argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf + argsDict["lag_shockCapturing"] = 0 + argsDict["shockCapturingDiffusion"] = 0.0 + argsDict["sc_uref"] = 0.0 + argsDict["sc_alpha"] = 0.0 + argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g + argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] + argsDict["elementDiameter"] = self.mesh.elementDiametersArray + argsDict["degree_polynomial"] = degree_polynomial + argsDict["u_dof"] = self.u[0].dof + argsDict["u_dof_old"] = self.u_dof_old + argsDict["velocity"] = self.q['velocity'] + argsDict["q_m"] = self.timeIntegration.m_tmp[0] + argsDict["q_u"] = self.q[('u',0)] + argsDict["q_dV"] = self.q[('dV_u',0)] + argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] + argsDict["cfl"] = self.q[('cfl',0)] + argsDict["q_numDiff_u"] = self.q[('cfl',0)] + argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] + argsDict["offset_u"] = self.offset[0] + argsDict["stride_u"] = self.stride[0] + argsDict["globalResidual"] = r + argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global + argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray + argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray + argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray + argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] + argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] + argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] + argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] + argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] + argsDict["ebqe_phi"] = self.ebqe[('u',0)] + argsDict["epsFact"] = 0.0 + argsDict["ebqe_u"] = self.ebqe[('u',0)] + argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] + argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE + # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION + argsDict["cE"] = self.coefficients.cE + argsDict["cK"] = self.coefficients.cK + # PARAMETERS FOR LOG BASED ENTROPY FUNCTION + argsDict["uL"] = self.coefficients.uL + argsDict["uR"] = self.coefficients.uR + # PARAMETERS FOR EDGE VISCOSITY + argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs + argsDict["NNZ"] = self.nnz + argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern + argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) + argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) + argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms + argsDict["globalJacobian"] = self.jacobian.getCSRrepresentation()[2] + # C matrices + argsDict["Cx"] = Cx + argsDict["Cy"] = Cy + argsDict["Cz"] = Cz + argsDict["CTx"] = CTx + argsDict["CTy"] = CTy + argsDict["CTz"] = CTz + argsDict["ML"] = self.ML + argsDict["delta_x_ij"] = self.delta_x_ij + # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE + argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE + # FLUX CORRECTED TRANSPORT + argsDict["dLow"] = self.dLow + argsDict["fluxMatrix"] = self.fluxMatrix + argsDict["uDotLow"] = self.uDotLow + argsDict["uLow"] = self.uLow + argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL + argsDict["min_s_bc"] = self.min_s_bc + argsDict["max_s_bc"] = self.max_s_bc + argsDict["quantDOFs"] = self.quantDOFs + argsDict["sLow"] = self.sLow + argsDict["sn"] = self.sn + if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG + self.calculateResidual = self.richards.calculateResidual + self.calculateJacobian = self.richards.calculateJacobian + else: + self.calculateResidual = self.richards.calculateResidual_entropy_viscosity + self.calculateJacobian = self.richards.calculateMassMatrix + if self.delta_x_ij is None: + self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') + self.calculateResidual(argsDict) + #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] + #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf + #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] + #self.timeIntegration.calculateElementCoefficients(self.q) + if self.forceStrongConditions:# + for cj in range(len(self.dirichletConditionsForceDOF)):# + for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): + r[self.offset[cj]+self.stride[cj]*dofN] = 0 + if self.stabilization: + self.stabilization.accumulateSubgridMassHistory(self.q) + logEvent("Global residual",level=9,data=r) + self.nonlinear_function_evaluations += 1 + if self.globalResidualDummy is None: + self.globalResidualDummy = np.zeros(r.shape,'d') + + def invert(self,u,r): + #u=s + #r=p + import pdb + import copy + """ + Calculate the element residuals and add in to the global residual + """ + self.sHigh[:] = u + rowptr, colind, nzval = self.jacobian.getCSRrepresentation() + nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix + r.fill(0.0) + rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() + else: + Cy = np.zeros(Cx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() + else: + Cz = np.zeros(Cx.shape, 'd') + rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() + if (self.nSpace_global == 2): + rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() + else: + CTy = np.zeros(CTx.shape, 'd') + if (self.nSpace_global == 3): + rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() + else: + CTz = np.zeros(CTx.shape, 'd') + + # This is dummy. I just care about the csr structure of the sparse matrix + nFree = len(rowptr)-1 + degree_polynomial = 1 + try: + degree_polynomial = self.u[0].femSpace.order + except: + pass + if self.delta_x_ij is None: + self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') + argsDict = cArgumentsDict.ArgumentsDict() + argsDict["dt"] = self.timeIntegration.dt + argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi + argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi + argsDict["mesh_dof"] = self.mesh.nodeArray + argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray + argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN + argsDict["mesh_l2g"] = self.mesh.elementNodesArray + argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] + argsDict["u_trial_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi + argsDict["u_test_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi + argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace + argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace + argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] + argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals + argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians + argsDict["nElements_global"] = self.mesh.nElements_global + argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] + argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, + argsDict["isSeepageFace"] = self.coefficients.isSeepageFace + argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] + argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] + argsDict["rho"] = self.coefficients.rho + argsDict["beta"] = self.coefficients.beta + argsDict["gravity"] = self.coefficients.gravity + argsDict["alpha"] = self.coefficients.vgm_alpha_types + argsDict["n"] = self.coefficients.vgm_n_types + argsDict["thetaR"] = self.coefficients.thetaR_types + argsDict["thetaSR"] = self.coefficients.thetaSR_types + argsDict["KWs"] = self.coefficients.Ksw_types + argsDict["useMetrics"] = 0.0 + argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf + argsDict["lag_shockCapturing"] = 0 + argsDict["shockCapturingDiffusion"] = 0.0 + argsDict["sc_uref"] = 0.0 + argsDict["sc_alpha"] = 0.0 + argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g + argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] + argsDict["elementDiameter"] = self.mesh.elementDiametersArray + argsDict["degree_polynomial"] = degree_polynomial + argsDict["u_dof"] = u#self.u[0].dof + argsDict["u_dof_old"] = self.u[0].dof + argsDict["velocity"] = self.q['velocity'] + argsDict["q_m"] = self.timeIntegration.m_tmp[0] + argsDict["q_u"] = self.q[('u',0)] + argsDict["q_dV"] = self.q[('dV_u',0)] + argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] + argsDict["cfl"] = self.q[('cfl',0)] + argsDict["q_numDiff_u"] = self.q[('cfl',0)] + argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] + argsDict["offset_u"] = self.offset[0] + argsDict["stride_u"] = self.stride[0] + argsDict["globalResidual"] = r + argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global + argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray + argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray + argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray + argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] + argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] + argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] + argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] + argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] + argsDict["ebqe_phi"] = self.ebqe[('u',0)] + argsDict["epsFact"] = 0.0 + argsDict["ebqe_u"] = self.ebqe[('u',0)] + argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] + argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE + # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION + argsDict["cE"] = self.coefficients.cE + argsDict["cK"] = self.coefficients.cK + # PARAMETERS FOR LOG BASED ENTROPY FUNCTION + argsDict["uL"] = self.coefficients.uL + argsDict["uR"] = self.coefficients.uR + # PARAMETERS FOR EDGE VISCOSITY + argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs + argsDict["NNZ"] = self.nnz + argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern + argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) + argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) + argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) + argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms + # C matrices + argsDict["Cx"] = Cx + argsDict["Cy"] = Cy + argsDict["Cz"] = Cz + argsDict["CTx"] = CTx + argsDict["CTy"] = CTy + argsDict["CTz"] = CTz + argsDict["ML"] = self.ML + argsDict["delta_x_ij"] = self.delta_x_ij + # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE + argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE + # FLUX CORRECTED TRANSPORT + argsDict["dLow"] = self.dLow + argsDict["fluxMatrix"] = self.fluxMatrix + argsDict["uDotLow"] = self.uDotLow + argsDict["uLow"] = self.uLow + argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL + argsDict["min_s_bc"] = self.min_s_bc + argsDict["max_s_bc"] = self.max_s_bc + argsDict["quantDOFs"] = self.quantDOFs + argsDict["sLow"] = self.sLow + argsDict["sn"] = self.sn + self.richards.invert(argsDict) + # self.timeIntegration.dt, + # self.u[0].femSpace.elementMaps.psi, + # self.u[0].femSpace.elementMaps.grad_psi, + # self.mesh.nodeArray, + # self.mesh.nodeVelocityArray, + # self.MOVING_DOMAIN, + # self.mesh.elementNodesArray, + # self.elementQuadratureWeights[('u',0)], + # self.u[0].femSpace.psi, + # self.u[0].femSpace.grad_psi, + # self.u[0].femSpace.psi, + # self.u[0].femSpace.grad_psi, + # #element boundary + # self.u[0].femSpace.elementMaps.psi_trace, + # self.u[0].femSpace.elementMaps.grad_psi_trace, + # self.elementBoundaryQuadratureWeights[('u',0)], + # self.u[0].femSpace.psi_trace, + # self.u[0].femSpace.grad_psi_trace, + # self.u[0].femSpace.psi_trace, + # self.u[0].femSpace.grad_psi_trace, + # self.u[0].femSpace.elementMaps.boundaryNormals, + # self.u[0].femSpace.elementMaps.boundaryJacobians, + # #physics + # self.mesh.nElements_global, + # self.ebqe['penalty'],#double* ebqe_penalty_ext, + # self.mesh.elementMaterialTypes,#int* elementMaterialTypes, + # self.coefficients.isSeepageFace, + # self.coefficients.sdInfo[(0,0)][0],#int* a_rowptr, + # self.coefficients.sdInfo[(0,0)][1],#int* a_colind, + # self.coefficients.rho,#double rho, + # self.coefficients.beta,#double beta, + # self.coefficients.gravity,#double* gravity, + # self.coefficients.vgm_alpha_types,#double* alpha, + # self.coefficients.vgm_n_types,#double* n, + # self.coefficients.thetaR_types,#double* thetaR, + # self.coefficients.thetaSR_types,#double* thetaSR, + # self.coefficients.Ksw_types,#double* KWs, + # False,#self.coefficients.useMetrics, + # self.timeIntegration.alpha_bdf, + # 0,#self.shockCapturing.lag, + # 0.0,#cek hack self.shockCapturing.shockCapturingFactor, + # 0.0,#self.coefficients.sc_uref, + # 0.0,#self.coefficients.sc_beta, + # self.u[0].femSpace.dofMap.l2g, + # self.l2g[0]['freeGlobal'], + # self.mesh.elementDiametersArray, + # degree_polynomial, + # self.sHigh, + # self.u_dof_old, + # self.q['velocity'],#self.coefficients.q_v, + # self.timeIntegration.m_tmp[0], + # self.q[('u',0)], + # self.timeIntegration.beta_bdf[0], + # self.q[('cfl',0)], + # self.edge_based_cfl, + # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff[0], + # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff_last[0], + # self.offset[0],self.stride[0], + # r, + # self.mesh.nExteriorElementBoundaries_global, + # self.mesh.exteriorElementBoundariesArray, + # self.mesh.elementBoundaryElementsArray, + # self.mesh.elementBoundaryLocalElementBoundariesArray, + # self.ebqe['velocity'],#self.coefficients.ebqe_v, + # self.numericalFlux.isDOFBoundary[0], + # self.numericalFlux.ebqe[('u',0)], + # self.ebqe[('advectiveFlux_bc_flag',0)], + # self.ebqe[('advectiveFlux_bc',0)], + # self.ebqe[('u',0)],#cek hack self.coefficients.ebqe_phi, + # 0.0,#cek hack self.coefficients.epsFact, + # self.ebqe[('u',0)], + # self.ebqe[('advectiveFlux',0)], + # # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION + # self.coefficients.cE, + # self.coefficients.cK, + # # PARAMETERS FOR LOG BASED ENTROPY FUNCTION + # self.coefficients.uL, + # self.coefficients.uR, + # # PARAMETERS FOR EDGE VISCOSITY + # len(rowptr) - 1, # num of DOFs + # len(Cx), # num of non-zero entries in the sparsity pattern + # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) + # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) + # self.csrRowIndeces[(0, 0)], # row indices (convenient for element loops) + # self.csrColumnOffsets[(0, 0)], # column indices (convenient for element loops) + # self.csrColumnOffsets_eb[(0, 0)], # indices for boundary terms + # # C matrices + # Cx, + # Cy, + # Cz, + # CTx, + # CTy, + # CTz, + # self.ML, + # self.delta_x_ij, + # # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD + # self.coefficients.LUMPED_MASS_MATRIX, + # self.coefficients.STABILIZATION_TYPE, + # self.coefficients.ENTROPY_TYPE, + # # FLUX CORRECTED TRANSPORT + # self.dLow, + # self.fluxMatrix, + # self.uDotLow, + # self.uLow, + # self.dt_times_dC_minus_dL, + # self.min_s_bc, + # self.max_s_bc, + # self.quantDOFs) + #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] + #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf + #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] + #self.timeIntegration.calculateElementCoefficients(self.q) + #if self.forceStrongConditions:# + # for cj in range(len(self.dirichletConditionsForceDOF)):# + # for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): + # r[self.offset[cj]+self.stride[cj]*dofN] = 0 + #if self.stabilization: + # self.stabilization.accumulateSubgridMassHistory(self.q) + #logEvent("Global residual",level=9,data=r) + #self.nonlinear_function_evaluations += 1 + #if self.globalResidualDummy is None: + # self.globalResidualDummy = numpy.zeros(r.shape,'d') + def getJacobian(self,jacobian): + if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG + cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, + jacobian) + degree_polynomial = 1 + try: + degree_polynomial = self.u[0].femSpace.order + except: + pass + if self.delta_x_ij is None: + self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') + argsDict = cArgumentsDict.ArgumentsDict() + argsDict["dt"] = self.timeIntegration.dt + argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi + argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi + argsDict["mesh_dof"] = self.mesh.nodeArray + argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray + argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN + argsDict["mesh_l2g"] = self.mesh.elementNodesArray + argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] + argsDict["u_trial_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi + argsDict["u_test_ref"] = self.u[0].femSpace.psi + argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi + argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace + argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace + argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] + argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace + argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace + argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals + argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians + argsDict["nElements_global"] = self.mesh.nElements_global + argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] + argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, + argsDict["isSeepageFace"] = self.coefficients.isSeepageFace + argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] + argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] + argsDict["rho"] = self.coefficients.rho + argsDict["beta"] = self.coefficients.beta + argsDict["gravity"] = self.coefficients.gravity + argsDict["alpha"] = self.coefficients.vgm_alpha_types + argsDict["n"] = self.coefficients.vgm_n_types + argsDict["thetaR"] = self.coefficients.thetaR_types + argsDict["thetaSR"] = self.coefficients.thetaSR_types + argsDict["KWs"] = self.coefficients.Ksw_types + argsDict["useMetrics"] = 0.0 + argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf + argsDict["lag_shockCapturing"] = 0 + argsDict["shockCapturingDiffusion"] = 0.0 + argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g + argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] + argsDict["elementDiameter"] = self.mesh.elementDiametersArray + argsDict["degree_polynomial"] = degree_polynomial + argsDict["u_dof"] = self.u[0].dof + argsDict["velocity"] = self.q['velocity'] + argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] + argsDict["cfl"] = self.q[('cfl',0)] + argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] + argsDict["csrRowIndeces_u_u"] = self.csrRowIndeces[(0,0)] + argsDict["csrColumnOffsets_u_u"] = self.csrColumnOffsets[(0,0)] + argsDict["globalJacobian"] = jacobian.getCSRrepresentation()[2] + argsDict["delta_x_ij"] = self.delta_x_ij + argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global + argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray + argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray + argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray + argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] + argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] + argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] + argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] + argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] + argsDict["csrColumnOffsets_eb_u_u"] = self.csrColumnOffsets_eb[(0,0)] + argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + self.calculateJacobian(argsDict) + if self.forceStrongConditions: + for dofN in list(self.dirichletConditionsForceDOF[0].DOFBoundaryConditionsDict.keys()): + global_dofN = self.offset[0]+self.stride[0]*dofN + self.nzval[np.where(self.colind == global_dofN)] = 0.0 #column + self.nzval[self.rowptr[global_dofN]:self.rowptr[global_dofN+1]] = 0.0 #row + zeroRow=True + for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]):#row + if (self.colind[i] == global_dofN): + self.nzval[i] = 1.0 + zeroRow = False + if zeroRow: + raise RuntimeError("Jacobian has a zero row because sparse matrix has no diagonal entry at row "+repr(global_dofN)+". You probably need add diagonal mass or reaction term") + #scaling = 1.0#probably want to add some scaling to match non-dirichlet diagonals in linear system + #for cj in range(self.nc): + # for dofN in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.keys()): + # global_dofN = self.offset[cj]+self.stride[cj]*dofN + # for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]): + # if (self.colind[i] == global_dofN): + # self.nzval[i] = scaling + # else: + # self.nzval[i] = 0.0 + logEvent("Jacobian ",level=10,data=jacobian) + #mwf decide if this is reasonable for solver statistics + self.nonlinear_function_jacobian_evaluations += 1 + return jacobian + def calculateElementQuadrature(self): + """ + Calculate the physical location and weights of the quadrature rules + and the shape information at the quadrature points. + + This function should be called only when the mesh changes. + """ + #self.u[0].femSpace.elementMaps.getValues(self.elementQuadraturePoints, + # self.q['x']) + self.u[0].femSpace.elementMaps.getBasisValuesRef(self.elementQuadraturePoints) + self.u[0].femSpace.elementMaps.getBasisGradientValuesRef(self.elementQuadraturePoints) + self.u[0].femSpace.getBasisValuesRef(self.elementQuadraturePoints) + self.u[0].femSpace.getBasisGradientValuesRef(self.elementQuadraturePoints) + self.coefficients.initializeElementQuadrature(self.timeIntegration.t,self.q) + if self.stabilization != None: + self.stabilization.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) + self.stabilization.initializeTimeIntegration(self.timeIntegration) + if self.shockCapturing != None: + self.shockCapturing.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) + def calculateElementBoundaryQuadrature(self): + pass + def calculateExteriorElementBoundaryQuadrature(self): + """ + Calculate the physical location and weights of the quadrature rules + and the shape information at the quadrature points on global element boundaries. + + This function should be called only when the mesh changes. + """ + # + #get physical locations of element boundary quadrature points + # + #assume all components live on the same mesh + self.u[0].femSpace.elementMaps.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.elementMaps.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) + self.u[0].femSpace.elementMaps.getValuesGlobalExteriorTrace(self.elementBoundaryQuadraturePoints, + self.ebqe['x']) + self.fluxBoundaryConditionsObjectsDict = dict([(cj,FluxBoundaryConditions(self.mesh, + self.nElementBoundaryQuadraturePoints_elementBoundary, + self.ebqe[('x')], + getAdvectiveFluxBoundaryConditions=self.advectiveFluxBoundaryConditionsSetterDict[cj], + getDiffusiveFluxBoundaryConditions=self.diffusiveFluxBoundaryConditionsSetterDictDict[cj])) + for cj in list(self.advectiveFluxBoundaryConditionsSetterDict.keys())]) + self.coefficients.initializeGlobalExteriorElementBoundaryQuadrature(self.timeIntegration.t,self.ebqe) + def estimate_mt(self): + pass + def calculateSolutionAtQuadrature(self): + pass + def calculateAuxiliaryQuantitiesAfterStep(self): + pass From 01f676d92e5f18a6badc6960856ef6ceb3f0802d Mon Sep 17 00:00:00 2001 From: abarua-ce Date: Tue, 16 Apr 2024 10:57:21 -0500 Subject: [PATCH 2/7] Added Richards.h and Richards.py from add_fct branch --- proteus/richards/Richards.h | 781 +++++++++++++++++++++++++---------- proteus/richards/Richards.py | 154 ++++++- 2 files changed, 701 insertions(+), 234 deletions(-) diff --git a/proteus/richards/Richards.h b/proteus/richards/Richards.h index 1adaaefeef..b1f54a2251 100644 --- a/proteus/richards/Richards.h +++ b/proteus/richards/Richards.h @@ -32,12 +32,15 @@ namespace proteus } namespace proteus + { class Richards_base { //The base class defining the interface public: - virtual ~Richards_base(){} + virtual ~Richards_base(){ + double anb_seepage_flux =1e-16; + } virtual void calculateResidual(arguments_dict& args)=0; virtual void calculateJacobian(arguments_dict& args)=0; virtual void invert(arguments_dict& args)=0; @@ -113,6 +116,7 @@ namespace proteus psiC = -u; m_vg = 1.0 - 1.0 / n_vg; thetaS = thetaR + thetaSR; + //std::cout<< "Thetas"< 0.0) { pcBar = alpha * psiC; @@ -172,7 +176,7 @@ namespace proteus } } } - + inline void evaluateInverseCoefficients(const int rowptr[nSpace], const int colind[nnz], @@ -183,7 +187,7 @@ namespace proteus const double n_vg, const double thetaR, const double thetaSR, - const double KWs[nnz], + const double KWs[nnz], double& u, const double& m, const double& dm, @@ -192,7 +196,7 @@ namespace proteus const double a[nnz], const double da[nnz]) { - double psiC, + register double psiC, pcBar,pcBar_n, sBar, thetaW, @@ -222,7 +226,6 @@ namespace proteus <<"psiC "<& mesh_trial_ref = args.array("mesh_trial_ref"); @@ -501,11 +521,26 @@ namespace proteus xt::pyarray& quantDOFs = args.array("quantDOFs"); xt::pyarray& sLow = args.array("sLow"); xt::pyarray& sn = args.array("sn"); - + assert(a_rowptr.data()[nSpace] == nnz); assert(a_rowptr.data()[nSpace] == nSpace); //cek should this be read in? double Ct_sge = 4.0; + //For flux Calculation + //double anb_seepage_flux=0.0; + //anb_seepage_flux = args["anb_seepage_flux"]; + //double anb_seepage_flux = args.scalar("anb_seepage_flux"); + //anb_seepage_flux=0.0; + + xt::pyarray& anb_seepage_flux_n = args.array("anb_seepage_flux_n"); + + + //double anb_seepage_flux=0.0; + double & anb_seepage_flux (args.scalar("anb_seepage_flux")) ; + //double anb_seepage_flux = args.scalar("anb_seepage_flux_n"); + + //double anb_seepage_flux=0.0; + anb_seepage_flux=0.0; //loop over elements to compute volume integrals and load them into element and global residual // @@ -519,7 +554,7 @@ namespace proteus for(int eN=0;eN0) + { + std::cout<<"The seepage flux is "<& max_s_bc = args.array("max_s_bc"); int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); int MONOLITHIC = args.scalar("MONOLITHIC"); - double Rpos[numDOFs], Rneg[numDOFs]; - double FluxCorrectionMatrix[NNZ]; - double solL[numDOFs]; - double sdot[numDOFs]; + register double Rpos[numDOFs], Rneg[numDOFs]; + register double FluxCorrectionMatrix[NNZ]; + register double solL[numDOFs]; + register double sdot[numDOFs]; ////////////////// // LOOP in DOFs // ////////////////// @@ -1476,7 +1542,7 @@ namespace proteus xt::pyarray& max_s_bc = args.array("max_s_bc"); int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); int MONOLITHIC = args.scalar("MONOLITHIC"); - double Rpos[numDOFs], Rneg[numDOFs]; + register double Rpos[numDOFs], Rneg[numDOFs]; int ij=0; ////////////////////////////////////////////////////// @@ -1527,16 +1593,16 @@ namespace proteus double Fluxij = FluxMatrix.data()[ij] - limitedFlux.data()[ij]; // compute limiter double Lij = 1.0; - Lij = (Fluxij>0 ? Rposi : Rpos[j]); + Lij = (Fluxij>0 ? Rposi : Rpos[j]); // compute limited flux ith_Limiter_times_FluxCorrectionMatrix += Lij*Fluxij; - + // update limited flux limitedFlux.data()[ij] = Lij*Fluxij; - + //update FluxMatrix - FluxMatrix.data()[ij] = Fluxij; - + FluxMatrix.data()[ij] = Fluxij; + //update ij ij+=1; } @@ -1575,7 +1641,7 @@ namespace proteus double Qnegi = mi*(mini-solLim.data()[i]); // compute R vectors // Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); + Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); } // COMPUTE LIMITERS // @@ -1623,6 +1689,7 @@ namespace proteus xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); xt::pyarray& dS_ref = args.array("dS_ref"); xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); @@ -1717,20 +1784,34 @@ namespace proteus xt::pyarray& quantDOFs = args.array("quantDOFs"); xt::pyarray& sLow = args.array("sLow"); xt::pyarray& sn = args.array("sn"); - double Rpos[numDOFs], Rneg[numDOFs]; - //double FluxCorrectionMatrix[NNZ]; + + xt::pyarray& anb_seepage_flux_n = args.array("anb_seepage_flux_n"); + + + //double anb_seepage_flux=0.0; + double & anb_seepage_flux (args.scalar("anb_seepage_flux")) ; + //double anb_seepage_flux = args.scalar("anb_seepage_flux_n"); + + //double anb_seepage_flux=0.0; + anb_seepage_flux=0.0; + + + register double Rpos[numDOFs], Rneg[numDOFs]; + //register double FluxCorrectionMatrix[NNZ]; // NOTE: This function follows a different (but equivalent) implementation of the smoothness based indicator than NCLS.h // Allocate space for the transport matrices // This is used for first order KUZMIN'S METHOD - double TransportMatrix[NNZ],TransportMatrixConsistent[NNZ]; - double TransportMatrixn[NNZ],TransportMatrixConsistentn[NNZ]; + register double TransportMatrix[NNZ],TransportMatrixConsistent[NNZ]; + register double TransportMatrixn[NNZ],TransportMatrixConsistentn[NNZ]; std::valarray u_free_dof(numDOFs); std::valarray u_free_dof_old(numDOFs); std::valarray ML2(numDOFs); + + for(int eN=0;eN= 0 && isFluxBoundary_u[ebNE_kb] != 1 ) //outflow. This is handled via the transport matrices. Then flux_ext=0 and dflux_ext!=0 */ - /* { */ - /* dflux_ext = flow; */ - /* flux_ext = 0; */ - /* // save external u */ - /* ebqe_u[ebNE_kb] = u_ext; */ - /* } */ - /* else // inflow. This is handled via the boundary integral. Then flux_ext!=0 and dflux_ext=0 */ - /* { */ - /* dflux_ext = 0; */ - /* // save external u */ - /* ebqe_u[ebNE_kb] = isDOFBoundary_u[ebNE_kb]*ebqe_bc_u_ext[ebNE_kb]+(1-isDOFBoundary_u[ebNE_kb])*u_ext; */ - /* if (isDOFBoundary_u[ebNE_kb] == 1) */ - /* flux_ext = ebqe_bc_u_ext[ebNE_kb]*flow; */ - /* else if (isFluxBoundary_u[ebNE_kb] == 1) */ - /* flux_ext = ebqe_bc_flux_u_ext[ebNE_kb]; */ - /* else */ - /* { */ - /* std::cout<<"warning: VOF open boundary with no external trace, setting to zero for inflow"<0) + { + std::cout<<"The seepage flux is "<("anb_seepage_flux_n"); + //anb_seepage_flux_n=0.0; + + //anb_seepage_flux_n= anb_seepage_flux; + + + + //if (isSeepageFace) + //{ + // anb_seepage_flux+= dS* flux_ext; + // std::cout<<"The seepage flux is "<0){ + // std::cout<<"The seepage flux is "<= 0 && isFluxBoundary_u[ebNE_kb] != 1 ) //outflow. This is handled via the transport matrices. Then flux_ext=0 and dflux_ext!=0 + // { + // dflux_ext = flow; + // flux_ext = 0; + // // save external u + // ebqe_u[ebNE_kb] = u_ext; + // } + //else // inflow. This is handled via the boundary integral. Then flux_ext!=0 and dflux_ext=0 + //{ + //dflux_ext = 0; + // save external u + //ebqe_u[ebNE_kb] = isDOFBoundary_u[ebNE_kb]*ebqe_bc_u_ext[ebNE_kb]+(1-isDOFBoundary_u[ebNE_kb])*u_ext; + //if (isDOFBoundary_u[ebNE_kb] == 1) + // flux_ext = ebqe_bc_u_ext[ebNE_kb]*flow; + //else if (isFluxBoundary_u[ebNE_kb] == 1) + //flux_ext = ebqe_bc_flux_u_ext[ebNE_kb]; + // flux_ext = ebqe_bc_u_ext[ebNE_kb]; + //else + // { + // std::cout<<"warning: VOF open boundary with no external trace, setting to zero for inflow"<& bc_mask = args.array("bc_mask"); + //int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern + //int numDOFs = args.scalar("numDOFs"); //number of DOFs + //double dt = args.scalar("dt"); + //xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) + + xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn + //xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn + //xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 + //xt::pyarray& uLow = args.array("uLow"); + //xt::pyarray& uDotLow = args.array("uDotLow"); + //xt::pyarray& limited_solution = args.array("limited_solution"); + xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces + xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets + //xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix + //xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices + //xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 + //xt::pyarray& max_s_bc = args.array("max_s_bc"); + //int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); + //int MONOLITHIC = args.scalar("MONOLITHIC"); + register double Rpos[numDOFs], Rneg[numDOFs]; + register double FluxCorrectionMatrix[NNZ]; + xt::pyarray& solLim = args.array("limited_solution"); + //register double solL[numDOFs]; + //register double sdot[numDOFs]; + + ij=0; + for (int i=0; i 0 ? 1. : 0.); + Pnegi += fij * (fij < 0 ? 1. : 0.); + //update ij + ij+=1; + } + + // compute Q vectors // + double mi = ML.data()[i]; + double Qposi = mi*(maxi-solLim.data()[i]); + double Qnegi = mi*(mini-solLim.data()[i]); + // compute R vectors // + Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); + Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); + } + + ij=0; + for (int i=0; i 0 ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j]); + // compute ith_limited_flux_correction + ith_limited_flux_correction += Lij*fij; + ij+=1; + } + double mi = ML.data()[i]; + solLim[i] += 1./mi*ith_limited_flux_correction; + } + + //std::cout<<"Limiter "<< ith_Limiter_times_FluxCorrectionMatrix < mMax) - { - std::cout<<"mass out of bounds "< mMax) + { + std::cout<<"mass out of bounds "< 1.0 || Rposi < 0.0) + //if (Rposi > 1.0 || Rposi < 0.0) //std::cout << "Rposi: " << Rposi << std::endl; - //if (Rnegi > 1.0 || Rnegi < 0.0) - //std::cout << "Rnegi: " << Rnegi << std::endl; - + //if (Rnegi > 1.0 || Rnegi < 0.0) + //std::cout << "Rnegi: " << Rnegi << std::endl; + // LOOP OVER THE SPARSITY PATTERN (j-LOOP)// // for (int offset=csrRowIndeces_DofLoops.data()[i]; // offset& a_rowptr = args.array("a_rowptr"); @@ -2719,7 +3056,7 @@ namespace proteus // for(int eN=0;eN(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, CompKernelFlag); else if (nSpaceIn == 2) return proteus::chooseAndAllocateDiscretization2D(nSpaceIn, @@ -2962,5 +3301,5 @@ namespace proteus CompKernelFlag); } } -}//proteus -#endif +};//proteus +#endif \ No newline at end of file diff --git a/proteus/richards/Richards.py b/proteus/richards/Richards.py index 841fcd0884..b299d490ce 100644 --- a/proteus/richards/Richards.py +++ b/proteus/richards/Richards.py @@ -12,6 +12,8 @@ from proteus.LinearAlgebraTools import SparseMat from proteus import TimeIntegration from proteus.NonlinearSolvers import ExplicitLumpedMassMatrixForRichards +from proteus.NonlinearSolvers import Newton + class ThetaScheme(TimeIntegration.BackwardEuler): def __init__(self,transport,integrateInterpolationPoints=False): @@ -51,6 +53,8 @@ def __init__(self, transport, timeOrder=1, runCFL=0.1, integrateInterpolationPoi self.u_dof_stage[ci] = [] for k in range(self.nStages + 1): self.u_dof_stage[ci].append(transport.u[ci].dof.copy()) + #print() + # def set_dt(self, DTSET): # self.dt = DTSET # don't update t @@ -63,6 +67,8 @@ def choose_dt(self): self.dtLast = self.dt self.t = self.tLast + self.dt self.substeps = [self.t for i in range(self.nStages)] # Manuel is ignoring different time step levels for now + #print("Hi, This is Arnob") + def initialize_dt(self, t0, tOut, q): """ @@ -134,6 +140,7 @@ def updateStage(self): for ci in range(self.nc): self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof[:] self.transport.u_dof_old[:] = self.transport.u[ci].dof + #self.print("Hi, Arnob") def initializeTimeHistory(self, resetFromDOF=True): """ @@ -199,6 +206,8 @@ def setFromOptions(self, nOptions): setattr(self, flag, val) if flag == 'timeOrder': self.resetOrder(self.timeOrder) + + class Coefficients(proteus.TransportCoefficients.TC_base): """ @@ -223,8 +232,7 @@ def __init__(self, ENTROPY_TYPE=2, # logarithmic LUMPED_MASS_MATRIX=False, MONOLITHIC=True, - FCT=False, - forceStrongBoundaryConditions=False, + FCT=True, num_fct_iter=1, # FOR ENTROPY VISCOSITY cE=1.0, @@ -233,7 +241,9 @@ def __init__(self, # FOR ARTIFICIAL COMPRESSION cK=1.0, # OUTPUT quantDOFs - outputQuantDOFs=False): + outputQuantDOFs=False, ): + self.anb_seepage_flux= 0.00 + #self.anb_seepage_flux_n =0.0 variableNames=['pressure_head'] nc=1 mass={0:{0:'nonlinear'}} @@ -294,7 +304,7 @@ def __init__(self, self.uL = uL self.uR = uR self.cK = cK - self.forceStrongConditions = forceStrongBoundaryConditions + self.forceStrongConditions = True self.cE = cE self.outputQuantDOFs = outputQuantDOFs TC_base.__init__(self, @@ -320,12 +330,15 @@ def initializeMesh(self,mesh): #mwf missing ebNE-->ebN? ebN = mesh.exteriorElementBoundariesArray[ebNE] #print "eb flag",mesh.elementBoundaryMaterialTypes[ebN] + #print("Hi, Arnob") #print self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) self.isSeepageFace[ebNE] = self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) - #print self.isSeepageFace + #print (self.isSeepageFace) def initializeElementQuadrature(self,t,cq): self.materialTypes_q = self.elementMaterialTypes self.q_shape = cq[('u',0)].shape + #self.anb_seepage_flux= anb_seepage_flux + #print("The seepage is ", anb_seepage_flux) # cq['Ks'] = np.zeros(self.q_shape,'d') # for k in range(self.q_shape[1]): # cq['Ks'][:,k] = self.Ksw_types[self.elementMaterialTypes,0] @@ -342,6 +355,8 @@ def initializeGlobalExteriorElementBoundaryQuadrature(self,t,cebqe): self.ebqe_shape = cebqe[('u',0)].shape self.ebqe[('vol_frac',0)] = np.zeros(self.ebqe_shape,'d') # + + def evaluate(self,t,c): if c[('u',0)].shape == self.q_shape: materialTypes = self.materialTypes_q @@ -402,11 +417,13 @@ def evaluate(self,t,c): np.isnan(c[('dm',0,0)]).any()): import pdb pdb.set_trace() - -# #mwf debug -# if c[('u',0)].shape == self.q_shape: -# c[('visPerm',0)]=c[('a',0,0)][:,:,0,0] - + + def postStep(self, t, firstStep=False): + # #anb_seepage_flux_n[:]= self.anb_seepage_flux + with open('seepage_stab_0', "a") as f: + # f.write("\n Time"+ ",\t" +"Seepage\n") + f.write(repr(t)+ ",\t")# +repr(np.sum(self.LevelModel.anb_seepage_flux_n))) + class LevelModel(proteus.Transport.OneLevelTransport): nCalls=0 def __init__(self, @@ -538,6 +555,7 @@ def __init__(self, for I in self.coefficients.elementIntegralKeys: if I in elementQuadrature: elementQuadratureDict[I] = elementQuadrature[I] + else: elementQuadratureDict[I] = elementQuadrature['default'] else: @@ -557,30 +575,50 @@ def __init__(self, if elemQuadIsDict: if ('numDiff',ci,ci) in elementQuadrature: elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature[('numDiff',ci,ci)] + #print("Hi, Arnob1") + #print(anb_seepage_flux) else: elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature['default'] + #print("Hi, Arnob2") + #print(anb_seepage_flux) else: elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature + print("Hi, Arnob3") + #print(anb_seepage_flux) if massLumping: for ci in list(self.coefficients.mass.keys()): elementQuadratureDict[('m',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + print("Hi, Arnob4") + #print(anb_seepage_flux) for I in self.coefficients.elementIntegralKeys: elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + print("Hi, Arnob5") + #print(anb_seepage_flux) if reactionLumping: for ci in list(self.coefficients.mass.keys()): elementQuadratureDict[('r',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + print("Hi, Arnob6") + #print(anb_seepage_flux) for I in self.coefficients.elementIntegralKeys: elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) + print("Hi, Arnob7") + #print(anb_seepage_flux) elementBoundaryQuadratureDict={} if isinstance(elementBoundaryQuadrature,dict): #set terms manually for I in self.coefficients.elementBoundaryIntegralKeys: if I in elementBoundaryQuadrature: elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature[I] + print("Hi, Arnob8") + #print(anb_seepage_flux) else: elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature['default'] + #print("Hi, Arnob9") + #print(anb_seepage_flux) else: for I in self.coefficients.elementBoundaryIntegralKeys: elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature + print("Hi, Arnob10") + #print(anb_seepage_flux) # # find the union of all element quadrature points and # build a quadrature rule for each integral that has a @@ -716,6 +754,21 @@ def __init__(self, assert cond, "Use lumped mass matrix just with: STABILIZATION_TYPE=2 (smoothness based stab.)" cond = 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards assert cond, "Use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards when the mass matrix is lumped" + + ################################################################# + ####################ARNOB_FCT_EDIT############################### + ################################################################# + + if self.coefficients.LUMPED_MASS_MATRIX == False: + cond = self.coefficients.STABILIZATION_TYPE == 2 + assert cond, "Use lumped mass matrix just with: STABILIZATION_TYPE=2 (smoothness based stab.)" + cond = 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == Newton + #assert cond, "Use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards when the mass matrix is lumped" + + + + + if self.coefficients.FCT == True: cond = self.coefficients.STABILIZATION_TYPE > 0, "Use FCT just with STABILIZATION_TYPE>0; i.e., edge based stabilization" # END OF ASSERTS @@ -739,6 +792,7 @@ def __init__(self, self.sLow = np.zeros(self.u[0].dof.shape, 'd') self.sHigh = np.zeros(self.u[0].dof.shape, 'd') self.sn = np.zeros(self.u[0].dof.shape, 'd') + self.anb_seepage_flux_n = np.zeros(self.u[0].dof.shape, 'd') comm = Comm.get() self.comm=comm if comm.size() > 1: @@ -749,6 +803,8 @@ def __init__(self, self.stride = [self.nc for ci in range(self.nc)] # logEvent(memory("stride+offset","OneLevelTransport"),level=4) + + if numericalFluxType != None: if options is None or options.periodicDirichletConditions is None: self.numericalFlux = numericalFluxType(self, @@ -821,7 +877,7 @@ def __init__(self, self.MOVING_DOMAIN=0.0 if self.mesh.nodeVelocityArray is None: self.mesh.nodeVelocityArray = np.zeros(self.mesh.nodeArray.shape,'d') - self.forceStrongConditions=self.coefficients.forceStrongConditions + self.forceStrongConditions=True self.dirichletConditionsForceDOF = {} if self.forceStrongConditions: for cj in range(self.nc): @@ -860,6 +916,7 @@ def FCTStep(self): argsDict["max_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0] + self.coefficients.thetaSR_types[0]) #cek hack argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX argsDict["MONOLITHIC"] =0#cek hack self.coefficients.MONOLITHIC + argsDict["anb_seepage_flux_n"]= self.anb_seepage_flux_n #pdb.set_trace() self.richards.FCTStep(argsDict) @@ -1177,8 +1234,7 @@ def getResidual(self,u,r): pass argsDict = cArgumentsDict.ArgumentsDict() - if self.forceStrongConditions: - argsDict["bc_mask"] = self.bc_mask + argsDict["bc_mask"] = self.bc_mask argsDict["dt"] = self.timeIntegration.dt argsDict["Theta"] = 1.0 argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi @@ -1292,6 +1348,29 @@ def getResidual(self,u,r): argsDict["quantDOFs"] = self.quantDOFs argsDict["sLow"] = self.sLow argsDict["sn"] = self.sn + argsDict["anb_seepage_flux_n"]= self.anb_seepage_flux_n +###################################################################################### + argsDict["pn"] = self.u[0].dof + argsDict["solH"] = self.sHigh + + rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() + argsDict["MassMatrix"] = MassMatrix + argsDict["solH"] = self.sHigh + +###################################################################################### + argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #print(anb_seepage_flux) + #argsDict["anb_seepage_flux_n"] = self.coefficients.anb_seepage_flux_n + #if np.sum(anb_seepage_flux_n)>0: + + #logEvent("Hi, this is Arnob", self.anb_seepage_flux_n[0]) + print("Seepage Flux from Python file", np.sum(self.anb_seepage_flux_n)) + seepage_text_variable= np.sum(self.anb_seepage_flux_n) + + with open('seepage_stab_0',"a" ) as f: + #f.write("\n Time"+ ",\t" +"Seepage\n") + #f.write(repr(self.coefficients.t)+ ",\t" +repr(seepage_text_variable), "\n") + f.write(repr(seepage_text_variable)+ "\n") if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG self.calculateResidual = self.richards.calculateResidual self.calculateJacobian = self.richards.calculateJacobian @@ -1316,6 +1395,13 @@ def getResidual(self,u,r): if self.globalResidualDummy is None: self.globalResidualDummy = np.zeros(r.shape,'d') + #print("Hello from the python file", self.coefficients.anb_seepage_flux) + #logEvent("Hello from the python file", self.coefficients.anb_seepage_flux") + + + + + def invert(self,u,r): #u=s #r=p @@ -1468,6 +1554,11 @@ def invert(self,u,r): argsDict["quantDOFs"] = self.quantDOFs argsDict["sLow"] = self.sLow argsDict["sn"] = self.sn + #Arnob trying to print flux + argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #print("Hi",anb_seepage_flux) + #print("Hi Seepage Flux", self.coefficients.anb_seepage_flux) + self.richards.invert(argsDict) # self.timeIntegration.dt, # self.u[0].femSpace.elementMaps.psi, @@ -1591,6 +1682,10 @@ def invert(self,u,r): #self.nonlinear_function_evaluations += 1 #if self.globalResidualDummy is None: # self.globalResidualDummy = numpy.zeros(r.shape,'d') + def postStep(self, t, firstStep=False): + with open('seepage_flux_nnnn', "a") as f: + f.write("\n Time"+ ",\t" +"Seepage\n") + f.write(repr(t)+ ",\t" +repr(self.coefficients.anb_seepage_flux)) def getJacobian(self,jacobian): if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, @@ -1666,6 +1761,21 @@ def getJacobian(self,jacobian): argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] argsDict["csrColumnOffsets_eb_u_u"] = self.csrColumnOffsets_eb[(0,0)] argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + + #arnob trying to calculate flux + #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #Arnob trying to print flux + #argsDict["anb_seepage_flux"] = self.calculateResidual.anb_seepage_flux + + #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #print("Hi Seepage Flux", self.coefficients.anb_seepage_flux) + #print("Hi Seepage Flux",anb_seepage_flux) + #print("The seepage is ", anb_seepage_flux) + + + + self.calculateJacobian(argsDict) if self.forceStrongConditions: for dofN in list(self.dirichletConditionsForceDOF[0].DOFBoundaryConditionsDict.keys()): @@ -1737,9 +1847,27 @@ def calculateExteriorElementBoundaryQuadrature(self): getDiffusiveFluxBoundaryConditions=self.diffusiveFluxBoundaryConditionsSetterDictDict[cj])) for cj in list(self.advectiveFluxBoundaryConditionsSetterDict.keys())]) self.coefficients.initializeGlobalExteriorElementBoundaryQuadrature(self.timeIntegration.t,self.ebqe) + #argsDict = cArgumentsDict.ArgumentsDict() + #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #print("Hi", self.coefficients.anb_seepage_flux) + + #print("The seepage is ", anb_seepage_flux) def estimate_mt(self): pass def calculateSolutionAtQuadrature(self): pass def calculateAuxiliaryQuantitiesAfterStep(self): pass + def postStep(self, t, firstStep=False): + with open('seepage_flux_nnnnk', "a") as f: + f.write("\n Time"+ ",\t" +"Seepage\n") + f.write(repr(t)+ ",\t" +repr(self.coefficients.anb_seepage_flux)) + + + +#argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux +#anb_seepage_flux= self.coefficients.anb_seepage_flux +#print("Hi",anb_seepage_flux) + + +#print("Hello from the python file", self.coefficients.anb_seepage_flux) From 644b0732fabb503286bf33a2d7cece04bbab2e23 Mon Sep 17 00:00:00 2001 From: abarua-ce Date: Tue, 16 Apr 2024 11:05:40 -0500 Subject: [PATCH 3/7] Removed the richards_fct directory --- richards_fct/richards/Richards.h | 3305 ---------------- richards_fct/richards/Richards.py | 1873 --------- richards_fct/richards/Richards_new.h | 2966 --------------- richards_fct/richards/Richards_new.py | 1745 --------- richards_fct/richards/__init__.py | 6 - richards_fct/richards/cRichards.cpp | 36 - richards_fct/richards/edit/Richards.h.save | 2967 --------------- richards_fct/richards/edit/Richards.h.save.1 | 2970 --------------- .../richards/edit/Richards.h:Zone.Identifier | 3 - .../richards/edit/Richards.py:Zone.Identifier | 3 - richards_fct/richards/edit/Richards_abc.h | 2967 --------------- richards_fct/richards/edit/Richards_abc.py | 1745 --------- .../richards/edit/Richards_corrupted.h | 3205 ---------------- .../richards/edit/Richards_corrupted.py | 1848 --------- richards_fct/richards/edit/Richards_edit.h | 3205 ---------------- richards_fct/richards/edit/Richards_edit_n.h | 3342 ----------------- richards_fct/richards/edit/Richards_edit_n.py | 1873 --------- richards_fct/richards/edit/Richards_fct.h | 3174 ---------------- richards_fct/richards/edit/Richards_n.py | 1840 --------- richards_fct/richards/edit/__init__.py | 6 - richards_fct/richards/edit/cRichards.cpp | 36 - richards_fct/richards/new_update/Richards.h | 2966 --------------- richards_fct/richards/new_update/Richards.py | 1745 --------- 23 files changed, 43826 deletions(-) delete mode 100644 richards_fct/richards/Richards.h delete mode 100644 richards_fct/richards/Richards.py delete mode 100644 richards_fct/richards/Richards_new.h delete mode 100644 richards_fct/richards/Richards_new.py delete mode 100644 richards_fct/richards/__init__.py delete mode 100644 richards_fct/richards/cRichards.cpp delete mode 100755 richards_fct/richards/edit/Richards.h.save delete mode 100755 richards_fct/richards/edit/Richards.h.save.1 delete mode 100644 richards_fct/richards/edit/Richards.h:Zone.Identifier delete mode 100644 richards_fct/richards/edit/Richards.py:Zone.Identifier delete mode 100644 richards_fct/richards/edit/Richards_abc.h delete mode 100644 richards_fct/richards/edit/Richards_abc.py delete mode 100644 richards_fct/richards/edit/Richards_corrupted.h delete mode 100644 richards_fct/richards/edit/Richards_corrupted.py delete mode 100755 richards_fct/richards/edit/Richards_edit.h delete mode 100644 richards_fct/richards/edit/Richards_edit_n.h delete mode 100644 richards_fct/richards/edit/Richards_edit_n.py delete mode 100644 richards_fct/richards/edit/Richards_fct.h delete mode 100755 richards_fct/richards/edit/Richards_n.py delete mode 100755 richards_fct/richards/edit/__init__.py delete mode 100755 richards_fct/richards/edit/cRichards.cpp delete mode 100644 richards_fct/richards/new_update/Richards.h delete mode 100644 richards_fct/richards/new_update/Richards.py diff --git a/richards_fct/richards/Richards.h b/richards_fct/richards/Richards.h deleted file mode 100644 index b1f54a2251..0000000000 --- a/richards_fct/richards/Richards.h +++ /dev/null @@ -1,3305 +0,0 @@ -#ifndef Richards_H -#define Richards_H -#include -#include -#include -#include "CompKernel.h" -#include "ModelFactory.h" -#include "../mprans/ArgumentsDict.h" -#include "xtensor-python/pyarray.hpp" -#define nnz nSpace - -namespace py = pybind11; -#define POWER_SMOOTHNESS_INDICATOR 2 -#define IS_BETAij_ONE 0 -#define GLOBAL_FCT 0 -namespace proteus -{ - // Power entropy // - inline double ENTROPY(const double& phi, const double& phiL, const double& phiR){ - return 1./2.*std::pow(fabs(phi),2.); - } - inline double DENTROPY(const double& phi, const double& phiL, const double& phiR){ - return fabs(phi)*(phi>=0 ? 1 : -1); - } - // Log entropy // for level set from 0 to 1 - inline double ENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ - return std::log(fabs((phi-phiL)*(phiR-phi))+1E-14); - } - inline double DENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ - return (phiL+phiR-2*phi)*((phi-phiL)*(phiR-phi)>=0 ? 1 : -1)/(fabs((phi-phiL)*(phiR-phi))+1E-14); - } -} - -namespace proteus - -{ - class Richards_base - { - //The base class defining the interface - public: - virtual ~Richards_base(){ - double anb_seepage_flux =1e-16; - } - virtual void calculateResidual(arguments_dict& args)=0; - virtual void calculateJacobian(arguments_dict& args)=0; - virtual void invert(arguments_dict& args)=0; - virtual void FCTStep(arguments_dict& args)=0; - virtual void kth_FCT_step(arguments_dict& args)=0; - virtual void calculateResidual_entropy_viscosity(arguments_dict& args)=0; - virtual void calculateMassMatrix(arguments_dict& args)=0; - }; - - template - class Richards : public Richards_base - { - public: - const int nDOF_test_X_trial_element; - CompKernelType ck; - Richards(): - nDOF_test_X_trial_element(nDOF_test_element*nDOF_trial_element), - ck() - {} - inline - void evaluateCoefficients(const int rowptr[nSpace], - const int colind[nnz], - const double rho, - const double beta, - const double gravity[nSpace], - const double alpha, - const double n_vg, - const double thetaR, - const double thetaSR, - const double KWs[nnz], - const double& u, - double& m, - double& dm, - double f[nSpace], - double df[nSpace], - double a[nnz], - double da[nnz], - double as[nnz], - double& kr, - double& dkr) - { - const int nSpace2 = nSpace * nSpace; - double psiC; - double pcBar; - double pcBar_n; - double pcBar_nM1; - double pcBar_nM2; - double onePlus_pcBar_n; - double sBar; - double sqrt_sBar; - double DsBar_DpsiC; - double thetaW; - double DthetaW_DpsiC; - double vBar; - double vBar2; - double DvBar_DpsiC; - double KWr; - double DKWr_DpsiC; - double rho2 = rho * rho; - double thetaS; - double rhom; - double drhom; - double m_vg; - double pcBarStar; - double sqrt_sBarStar; - - psiC = -u; - m_vg = 1.0 - 1.0 / n_vg; - thetaS = thetaR + thetaSR; - //std::cout<< "Thetas"< 0.0) - { - pcBar = alpha * psiC; - pcBarStar = pcBar; - if (pcBar < 1.0e-8) - pcBarStar = 1.0e-8; - pcBar_nM2 = pow(pcBarStar, n_vg - 2); - pcBar_nM1 = pcBar_nM2 * pcBar; - pcBar_n = pcBar_nM1 * pcBar; - onePlus_pcBar_n = 1.0 + pcBar_n; - - sBar = pow(onePlus_pcBar_n, -m_vg); - /* using -mn = 1-n */ - DsBar_DpsiC = alpha * (1.0 - n_vg) * (sBar/onePlus_pcBar_n)*pcBar_nM1; - - vBar = 1.0-pcBar_nM1*sBar; - vBar2 = vBar*vBar; - DvBar_DpsiC = -alpha*(n_vg-1.0)*pcBar_nM2*sBar - pcBar_nM1*DsBar_DpsiC; - - thetaW = thetaSR*sBar + thetaR; - DthetaW_DpsiC = thetaSR * DsBar_DpsiC; - - sqrt_sBar = sqrt(sBar); - sqrt_sBarStar = sqrt_sBar; - if (sqrt_sBar < 1.0e-8) - sqrt_sBarStar = 1.0e-8; - KWr= sqrt_sBar*vBar2; - DKWr_DpsiC= ((0.5/sqrt_sBarStar)*DsBar_DpsiC*vBar2 - + - 2.0*sqrt_sBar*vBar*DvBar_DpsiC); - } - else - { - thetaW = thetaS; - DthetaW_DpsiC = 0.0; - KWr = 1.0; - DKWr_DpsiC = 0.0; - } - //slight compressibility - rhom = rho*exp(beta*u); - drhom = beta*rhom; - m = rhom*thetaW; - dm = -rhom*DthetaW_DpsiC+drhom*thetaW; - for (int I=0;I thetaS || thetaW <= thetaR) - { - //cek debug - std::cout<<"rho "< 0.0) - { - isDOFBoundary = 1; - bc_u = bc_u_seepage; - } - else - { - isDOFBoundary = 0; - flux = 0.0; - } - } - /* //set DOF flag and flux correctly if seepage face */ - /* if (isSeepageFace) */ - /* { */ - /* if (flux < 0.0 || u < bc_u_seepage) */ - /* { */ - /* isDOFBoundary = 0; */ - /* flux = 0.0; */ - /* } */ - /* else */ - /* { */ - /* isDOFBoundary = 1; */ - /* bc_u = bc_u_seepage; */ - /* } */ - /* } */ - /* //Dirichlet penalty */ - /* if (isDOFBoundary) */ - /* flux += penalty*(u-bc_u); */ - } - else - flux = bc_flux; - } - - void exteriorNumericalFluxJacobian(const int rowptr[nSpace], - const int colind[nnz], - const int isDOFBoundary, - const double n[nSpace], - const double K[nnz], - const double dK[nnz], - const double grad_psi[nSpace], - const double grad_v[nSpace], - const double dK_rho_g[nSpace], - const double v, - const double penalty, - double& fluxJacobian) - { - if (isDOFBoundary) - { - fluxJacobian = 0.0; - for(int I=0;I& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - double sc_uref = args.scalar("sc_uref"); - double sc_alpha = args.scalar("sc_alpha"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& u_dof_old = args.array("u_dof_old"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m = args.array("q_m"); - xt::pyarray& q_u = args.array("q_u"); - xt::pyarray& q_dV = args.array("q_dV"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - int offset_u = args.scalar("offset_u"); - int stride_u = args.scalar("stride_u"); - xt::pyarray& globalResidual = args.array("globalResidual"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& ebqe_phi = args.array("ebqe_phi"); - double epsFact = args.scalar("epsFact"); - xt::pyarray& ebqe_u = args.array("ebqe_u"); - xt::pyarray& ebqe_flux = args.array("ebqe_flux"); - // PARAMETERS FOR EDGE BASED STABILIZATION - double cE = args.scalar("cE"); - double cK = args.scalar("cK"); - // PARAMETERS FOR LOG BASED ENTROPY FUNCTION - double uL = args.scalar("uL"); - double uR = args.scalar("uR"); - // PARAMETERS FOR EDGE VISCOSITY - int numDOFs = args.scalar("numDOFs"); - int NNZ = args.scalar("NNZ"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); - xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); - xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); - xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); - // C matrices - xt::pyarray& Cx = args.array("Cx"); - xt::pyarray& Cy = args.array("Cy"); - xt::pyarray& Cz = args.array("Cz"); - xt::pyarray& CTx = args.array("CTx"); - xt::pyarray& CTy = args.array("CTy"); - xt::pyarray& CTz = args.array("CTz"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); - int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); - // FOR FCT - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& fluxMatrix = args.array("fluxMatrix"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); - xt::pyarray& min_s_bc = args.array("min_s_bc"); - xt::pyarray& max_s_bc = args.array("max_s_bc"); - // AUX QUANTITIES OF INTEREST - xt::pyarray& quantDOFs = args.array("quantDOFs"); - xt::pyarray& sLow = args.array("sLow"); - xt::pyarray& sn = args.array("sn"); - - assert(a_rowptr.data()[nSpace] == nnz); - assert(a_rowptr.data()[nSpace] == nSpace); - //cek should this be read in? - double Ct_sge = 4.0; - //For flux Calculation - //double anb_seepage_flux=0.0; - //anb_seepage_flux = args["anb_seepage_flux"]; - //double anb_seepage_flux = args.scalar("anb_seepage_flux"); - //anb_seepage_flux=0.0; - - xt::pyarray& anb_seepage_flux_n = args.array("anb_seepage_flux_n"); - - - //double anb_seepage_flux=0.0; - double & anb_seepage_flux (args.scalar("anb_seepage_flux")) ; - //double anb_seepage_flux = args.scalar("anb_seepage_flux_n"); - - //double anb_seepage_flux=0.0; - anb_seepage_flux=0.0; - - //loop over elements to compute volume integrals and load them into element and global residual - // - //eN is the element index - //eN_k is the quadrature point index for a scalar - //eN_k_nSpace is the quadrature point index for a vector - //eN_i is the element test function index - //eN_j is the element trial function index - //eN_k_j is the quadrature point index for a trial function - //eN_k_i is the quadrature point index for a trial function - for(int eN=0;eN0) - { - std::cout<<"The seepage flux is "<& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); - xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); - xt::pyarray& globalJacobian = args.array("globalJacobian"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - assert(a_rowptr.data()[nSpace] == nnz); - assert(a_rowptr.data()[nSpace] == nSpace); - double Ct_sge = 4.0; - - - // - //loop over elements to compute volume integrals and load them into the element Jacobians and global Jacobian - // - for(int eN=0;eN& bc_mask = args.array("bc_mask"); - int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern - int numDOFs = args.scalar("numDOFs"); //number of DOFs - double dt = args.scalar("dt"); - xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) - xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn - xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn - xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& limited_solution = args.array("limited_solution"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets - xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices - xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 - xt::pyarray& max_s_bc = args.array("max_s_bc"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int MONOLITHIC = args.scalar("MONOLITHIC"); - register double Rpos[numDOFs], Rneg[numDOFs]; - register double FluxCorrectionMatrix[NNZ]; - register double solL[numDOFs]; - register double sdot[numDOFs]; - ////////////////// - // LOOP in DOFs // - ////////////////// - int ij=0; - for (int i=0; i 0) ? 1. : 0.); - Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); - - //update ij - ij+=1; - //std::cout<<"sdoti error"<0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])) - * FluxCorrectionMatrix[ij]; - alpha_dot = fmin(1.0, beta_ij*fabs(alpha_fA)/MassMatrix.data()[ij]/fmax(1.0e-8,fabs(sdoti-sdotj))); - if (MONOLITHIC == 0) - { - ith_Limiter_times_FluxCorrectionMatrix += alpha_fA; - } - else - { - ith_Limiter_times_FluxCorrectionMatrix += alpha_fA + (LUMPED_MASS_MATRIX == 1 ? 0. : 1.)*dt*alpha_dot*MassMatrix.data()[ij]*(sdoti-sdotj); - } - //update ij - ij+=1; - } - limited_solution.data()[i] = solL[i] + 1./lumped_mass_matrix.data()[i]*ith_Limiter_times_FluxCorrectionMatrix*bc_mask[i]; - } - } - - void kth_FCT_step(arguments_dict& args) - { - int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern - int numDOFs = args.scalar("numDOFs"); //number of DOFs - int num_fct_iter = args.scalar("num_fct_iter"); - double dt = args.scalar("dt"); - xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) - xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn - xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn - xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& solLim = args.array("limited_solution"); - xt::pyarray& MC = args.array("MC"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& FluxMatrix = args.array("FluxMatrix"); - xt::pyarray& limitedFlux = args.array("limited_Flux"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets - xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices - xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 - xt::pyarray& max_s_bc = args.array("max_s_bc"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int MONOLITHIC = args.scalar("MONOLITHIC"); - register double Rpos[numDOFs], Rneg[numDOFs]; - int ij=0; - - ////////////////////////////////////////////////////// - // ********** COMPUTE LOW ORDER SOLUTION ********** // - ////////////////////////////////////////////////////// - if (num_fct_iter == 0) - { // No FCT for global bounds - for (int i=0; i 0) ? 1. : 0.); - // update ij - ij+=1; - } - // compute Q vectors - double mi = ML.data()[i]; - double solLimi = solLim.data()[i]; - double Qposi = mi*(maxi-solLimi); - // compute R vectors - Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - } - ij=0; - for (int i=0; i0 ? Rposi : Rpos[j]); - // compute limited flux - ith_Limiter_times_FluxCorrectionMatrix += Lij*Fluxij; - - // update limited flux - limitedFlux.data()[ij] = Lij*Fluxij; - - //update FluxMatrix - FluxMatrix.data()[ij] = Fluxij; - - //update ij - ij+=1; - } - //update limited solution - double mi = ML.data()[i]; - solLim.data()[i] += 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; - } - } - } - - // ***************************************** // - // ********** HIGH ORDER SOLUTION ********** // - // ***************************************** // - ij=0; - for (int i=0; i 0 ? 1. : 0.); - Pnegi += fij * (fij < 0 ? 1. : 0.); - //update ij - ij+=1; - } - // compute Q vectors // - double mi = ML.data()[i]; - double Qposi = mi*(maxi-solLim.data()[i]); - double Qnegi = mi*(mini-solLim.data()[i]); - // compute R vectors // - Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); - } - - // COMPUTE LIMITERS // - ij=0; - for (int i=0; i 0 ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j]); - // compute ith_limited_flux_correction - ith_limited_flux_correction += Lij*fij; - ij+=1; - } - double mi = ML.data()[i]; - solLim[i] += 1./mi*ith_limited_flux_correction; - } - } - - void calculateResidual_entropy_viscosity(arguments_dict& args) - { - xt::pyarray& globalJacobian = args.array("globalJacobian"); - double Theta = args.scalar("Theta"); - xt::pyarray& bc_mask = args.array("bc_mask"); - double dt = args.scalar("dt"); - xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - double sc_uref = args.scalar("sc_uref"); - double sc_alpha = args.scalar("sc_alpha"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& r_l2g = args.array("r_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - int degree_polynomial = args.scalar("degree_polynomial"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& u_dof_old = args.array("u_dof_old"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m = args.array("q_m"); - xt::pyarray& q_u = args.array("q_u"); - xt::pyarray& q_dV = args.array("q_dV"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - int offset_u = args.scalar("offset_u"); - int stride_u = args.scalar("stride_u"); - xt::pyarray& globalResidual = args.array("globalResidual"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& ebqe_phi = args.array("ebqe_phi"); - double epsFact = args.scalar("epsFact"); - xt::pyarray& ebqe_u = args.array("ebqe_u"); - xt::pyarray& ebqe_flux = args.array("ebqe_flux"); - // PARAMETERS FOR EDGE BASED STABILIZATION - double cE = args.scalar("cE"); - double cK = args.scalar("cK"); - // PARAMETERS FOR LOG BASED ENTROPY FUNCTION - double uL = args.scalar("uL"); - double uR = args.scalar("uR"); - // PARAMETERS FOR EDGE VISCOSITY - int numDOFs = args.scalar("numDOFs"); - int NNZ = args.scalar("NNZ"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); - xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); - xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); - xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); - // C matrices - xt::pyarray& Cx = args.array("Cx"); - xt::pyarray& Cy = args.array("Cy"); - xt::pyarray& Cz = args.array("Cz"); - xt::pyarray& CTx = args.array("CTx"); - xt::pyarray& CTy = args.array("CTy"); - xt::pyarray& CTz = args.array("CTz"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); - int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); - // FOR FCT - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& fluxMatrix = args.array("fluxMatrix"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); - xt::pyarray& min_s_bc = args.array("min_s_bc"); - xt::pyarray& max_s_bc = args.array("max_s_bc"); - // AUX QUANTITIES OF INTEREST - xt::pyarray& quantDOFs = args.array("quantDOFs"); - xt::pyarray& sLow = args.array("sLow"); - xt::pyarray& sn = args.array("sn"); - - xt::pyarray& anb_seepage_flux_n = args.array("anb_seepage_flux_n"); - - - //double anb_seepage_flux=0.0; - double & anb_seepage_flux (args.scalar("anb_seepage_flux")) ; - //double anb_seepage_flux = args.scalar("anb_seepage_flux_n"); - - //double anb_seepage_flux=0.0; - anb_seepage_flux=0.0; - - - register double Rpos[numDOFs], Rneg[numDOFs]; - //register double FluxCorrectionMatrix[NNZ]; - // NOTE: This function follows a different (but equivalent) implementation of the smoothness based indicator than NCLS.h - // Allocate space for the transport matrices - // This is used for first order KUZMIN'S METHOD - register double TransportMatrix[NNZ],TransportMatrixConsistent[NNZ]; - register double TransportMatrixn[NNZ],TransportMatrixConsistentn[NNZ]; - std::valarray u_free_dof(numDOFs); - std::valarray u_free_dof_old(numDOFs); - std::valarray ML2(numDOFs); - - - for(int eN=0;eN0) - { - std::cout<<"The seepage flux is "<("anb_seepage_flux_n"); - //anb_seepage_flux_n=0.0; - - //anb_seepage_flux_n= anb_seepage_flux; - - - - //if (isSeepageFace) - //{ - // anb_seepage_flux+= dS* flux_ext; - // std::cout<<"The seepage flux is "<0){ - // std::cout<<"The seepage flux is "<= 0 && isFluxBoundary_u[ebNE_kb] != 1 ) //outflow. This is handled via the transport matrices. Then flux_ext=0 and dflux_ext!=0 - // { - // dflux_ext = flow; - // flux_ext = 0; - // // save external u - // ebqe_u[ebNE_kb] = u_ext; - // } - //else // inflow. This is handled via the boundary integral. Then flux_ext!=0 and dflux_ext=0 - //{ - //dflux_ext = 0; - // save external u - //ebqe_u[ebNE_kb] = isDOFBoundary_u[ebNE_kb]*ebqe_bc_u_ext[ebNE_kb]+(1-isDOFBoundary_u[ebNE_kb])*u_ext; - //if (isDOFBoundary_u[ebNE_kb] == 1) - // flux_ext = ebqe_bc_u_ext[ebNE_kb]*flow; - //else if (isFluxBoundary_u[ebNE_kb] == 1) - //flux_ext = ebqe_bc_flux_u_ext[ebNE_kb]; - // flux_ext = ebqe_bc_u_ext[ebNE_kb]; - //else - // { - // std::cout<<"warning: VOF open boundary with no external trace, setting to zero for inflow"<= 0.) - { - alpha_numerator_pos += alpha_num; - alpha_denominator_pos += alpha_num; - } - else - { - alpha_numerator_neg += alpha_num; - alpha_denominator_neg += fabs(alpha_num); - } - //update ij - ij+=1; - } - // scale g vector by lumped mass matrix - if (fabs(ML.data()[i] - ML2[i]) > 1.0e-16) - std::cout<<"ML "< 0.0) - // assert( (xi[I] - xj[I]) == delta_x_ij[offset*3+I]); - //gi_times_x += gi[I]*(xi[I]-xj[I]); - gi_times_x += gi[I]*delta_x_ij.data()[offset*3+I]; - } - // compute the positive and negative part of gi*(xi-xj) - SumPos += gi_times_x > 0 ? gi_times_x : 0; - SumNeg += gi_times_x < 0 ? gi_times_x : 0; - } - double sigmaPosi = fmin(1.,(fabs(SumNeg)+1E-15)/(SumPos+1E-15)); - double sigmaNegi = fmin(1.,(SumPos+1E-15)/(fabs(SumNeg)+1E-15)); - double alpha_numi = fabs(sigmaPosi*alpha_numerator_pos + sigmaNegi*alpha_numerator_neg); - double alpha_deni = sigmaPosi*alpha_denominator_pos + sigmaNegi*alpha_denominator_neg; - if (IS_BETAij_ONE == 1) - { - alpha_numi = fabs(alpha_numerator_pos + alpha_numerator_neg); - alpha_deni = alpha_denominator_pos + alpha_denominator_neg; - } - double alphai = alpha_numi/(alpha_deni+1E-15); - quantDOFs.data()[i] = alphai; - - if (POWER_SMOOTHNESS_INDICATOR==0) - psi[i] = 1.0; - else - psi[i] = std::pow(alphai,POWER_SMOOTHNESS_INDICATOR); //NOTE: they use alpha^2 in the paper - } - ///////////////////////////////////////////// - // ** LOOP IN DOFs FOR EDGE BASED TERMS ** // - ///////////////////////////////////////////// - ij=0; - for (int i=0; i Dissipation matrices as well. - double soli = u_free_dof[i]; // solution at time tn for the ith DOF - double solni = u_free_dof_old[i]; // solution at time tn for the ith DOF - for (int I=0;I& bc_mask = args.array("bc_mask"); - //int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern - //int numDOFs = args.scalar("numDOFs"); //number of DOFs - //double dt = args.scalar("dt"); - //xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) - - xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn - //xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn - //xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 - //xt::pyarray& uLow = args.array("uLow"); - //xt::pyarray& uDotLow = args.array("uDotLow"); - //xt::pyarray& limited_solution = args.array("limited_solution"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets - //xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix - //xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices - //xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 - //xt::pyarray& max_s_bc = args.array("max_s_bc"); - //int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - //int MONOLITHIC = args.scalar("MONOLITHIC"); - register double Rpos[numDOFs], Rneg[numDOFs]; - register double FluxCorrectionMatrix[NNZ]; - xt::pyarray& solLim = args.array("limited_solution"); - //register double solL[numDOFs]; - //register double sdot[numDOFs]; - - ij=0; - for (int i=0; i 0 ? 1. : 0.); - Pnegi += fij * (fij < 0 ? 1. : 0.); - //update ij - ij+=1; - } - - // compute Q vectors // - double mi = ML.data()[i]; - double Qposi = mi*(maxi-solLim.data()[i]); - double Qnegi = mi*(mini-solLim.data()[i]); - // compute R vectors // - Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); - } - - ij=0; - for (int i=0; i 0 ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j]); - // compute ith_limited_flux_correction - ith_limited_flux_correction += Lij*fij; - ij+=1; - } - double mi = ML.data()[i]; - solLim[i] += 1./mi*ith_limited_flux_correction; - } - - //std::cout<<"Limiter "<< ith_Limiter_times_FluxCorrectionMatrix < mMax) - { - std::cout<<"mass out of bounds "< 0) ? 1. : 0.); - // Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); - // ij+=1; - // } - // double mi = ML[i]; - // double solni = u_dof_old[i]; - // double Qposi = mi*(maxi-solni); - // double Qnegi = mi*(mini-solni); - - //std::cout << Qposi << std::endl; - // Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - // Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); - - //if (Rpos[i] < 0) - //{ - // std::cout << mi << "\t" << maxi << "\t" << solni << std::endl; - // std::cout << Qposi << "\t" << Pposi << std::endl; - // std::cout << Rpos[i] << std::endl; - //abort(); - //} - //} - - //ij=0; - //for (int i=0; i 1.0 || Rposi < 0.0) - //std::cout << "Rposi: " << Rposi << std::endl; - //if (Rnegi > 1.0 || Rnegi < 0.0) - //std::cout << "Rnegi: " << Rnegi << std::endl; - - // LOOP OVER THE SPARSITY PATTERN (j-LOOP)// - // for (int offset=csrRowIndeces_DofLoops.data()[i]; - // offset0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])); - // //Lij=0.0; - // ith_Limiter_times_FluxCorrectionMatrix += Lij*FluxCorrectionMatrix[ij]; - // //update ij - // ij+=1; - // } - // double mi = ML[i]; - // double solni = u_dof_old[i]; - // globalResidual[i] = solni + 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; - //} - } - - - void invert(arguments_dict& args) - { - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - xt::pyarray& globalResidual = args.array("globalResidual"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - int numDOFs = args.scalar("numDOFs"); - for (int i=0; i mMax) - { - std::cout<<"mass out of bounds "<("dt"); - xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - //element boundary - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - //physics - int nElements_global = args.scalar("nElements_global"); - //new - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - //end new - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& r_l2g = args.array("r_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - int degree_polynomial = args.scalar("degree_polynomial"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); - xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); - xt::pyarray& globalJacobian = args.array("globalJacobian"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - //std::cout<<"ndjaco address "<(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - else if (nSpaceIn == 2) - return proteus::chooseAndAllocateDiscretization2D(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - else - { - assert(nSpaceIn == 3); - return proteus::chooseAndAllocateDiscretization(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - } - } -};//proteus -#endif \ No newline at end of file diff --git a/richards_fct/richards/Richards.py b/richards_fct/richards/Richards.py deleted file mode 100644 index b299d490ce..0000000000 --- a/richards_fct/richards/Richards.py +++ /dev/null @@ -1,1873 +0,0 @@ -from __future__ import division -from builtins import range -from past.utils import old_div -import proteus -from .cRichards import * -import numpy as np -from proteus.Transport import OneLevelTransport -from proteus.Transport import TC_base, NonlinearEquation, logEvent, memory -from proteus.Transport import FluxBoundaryConditions, Comm, cfemIntegrals -from proteus.Transport import DOFBoundaryConditions, Quadrature -from proteus.mprans import cArgumentsDict -from proteus.LinearAlgebraTools import SparseMat -from proteus import TimeIntegration -from proteus.NonlinearSolvers import ExplicitLumpedMassMatrixForRichards -from proteus.NonlinearSolvers import Newton - - -class ThetaScheme(TimeIntegration.BackwardEuler): - def __init__(self,transport,integrateInterpolationPoints=False): - self.transport=transport - TimeIntegration.BackwardEuler.__init__(self,transport, integrateInterpolationPoints) - def updateTimeHistory(self,resetFromDOF=False): - TimeIntegration.BackwardEuler.updateTimeHistory(self,resetFromDOF) - self.transport.u_dof_old[:] = self.u -class RKEV(TimeIntegration.SSP): - from proteus import TimeIntegration - """ - Wrapper for SSPRK time integration using EV - - ... more to come ... - """ - - def __init__(self, transport, timeOrder=1, runCFL=0.1, integrateInterpolationPoints=False): - TimeIntegration.SSP.__init__(self, transport, integrateInterpolationPoints=integrateInterpolationPoints) - self.runCFL = runCFL - self.dtLast = None - self.isAdaptive = True - # About the cfl - assert transport.coefficients.STABILIZATION_TYPE > 0, "SSP method just works for edge based EV methods; i.e., STABILIZATION_TYPE>0" - assert hasattr(transport, 'edge_based_cfl'), "No edge based cfl defined" - self.cfl = transport.edge_based_cfl - # Stuff particular for SSP - self.timeOrder = timeOrder # order of approximation - self.nStages = timeOrder # number of stages total - self.lstage = 0 # last stage completed - # storage vectors - self.u_dof_last = {} - # per component stage values, list with array at each stage - self.u_dof_stage = {} - for ci in range(self.nc): - if ('m', ci) in transport.q: - self.u_dof_last[ci] = transport.u[ci].dof.copy() - self.u_dof_stage[ci] = [] - for k in range(self.nStages + 1): - self.u_dof_stage[ci].append(transport.u[ci].dof.copy()) - #print() - - - # def set_dt(self, DTSET): - # self.dt = DTSET # don't update t - def choose_dt(self): - comm = Comm.get() - maxCFL = 1.0e-6 - maxCFL = max(maxCFL, comm.globalMax(self.cfl.max())) - self.dt = old_div(self.runCFL, maxCFL) - if self.dtLast is None: - self.dtLast = self.dt - self.t = self.tLast + self.dt - self.substeps = [self.t for i in range(self.nStages)] # Manuel is ignoring different time step levels for now - #print("Hi, This is Arnob") - - - def initialize_dt(self, t0, tOut, q): - """ - Modify self.dt - """ - self.tLast = t0 - self.choose_dt() - self.t = t0 + self.dt - - def setCoefficients(self): - """ - beta are all 1's here - mwf not used right now - """ - self.alpha = np.zeros((self.nStages, self.nStages), 'd') - self.dcoefs = np.zeros((self.nStages), 'd') - - def updateStage(self): - """ - Need to switch to use coefficients - """ - self.lstage += 1 - assert self.timeOrder in [1, 2, 3] - assert self.lstage > 0 and self.lstage <= self.timeOrder - if self.timeOrder == 3: - if self.lstage == 1: - logEvent("First stage of SSP33 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - # update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] - elif self.lstage == 2: - logEvent("Second stage of SSP33 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - self.u_dof_stage[ci][self.lstage] *= old_div(1., 4.) - self.u_dof_stage[ci][self.lstage] += 3. / 4. * self.u_dof_last[ci] - # Update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] - elif self.lstage == 3: - logEvent("Third stage of SSP33 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - self.u_dof_stage[ci][self.lstage] *= old_div(2.0, 3.0) - self.u_dof_stage[ci][self.lstage] += 1.0 / 3.0 * self.u_dof_last[ci] - # update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_last[ci] - # update solution to u[0].dof - self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] - elif self.timeOrder == 2: - if self.lstage == 1: - logEvent("First stage of SSP22 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - # Update u_dof_old - self.transport.u_dof_old[:] = self.transport.u[ci].dof - elif self.lstage == 2: - logEvent("Second stage of SSP22 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - self.u_dof_stage[ci][self.lstage][:] *= old_div(1., 2.) - self.u_dof_stage[ci][self.lstage][:] += 1. / 2. * self.u_dof_last[ci] - # update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_last[ci] - # update solution to u[0].dof - self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] - else: - assert self.timeOrder == 1 - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof[:] - self.transport.u_dof_old[:] = self.transport.u[ci].dof - #self.print("Hi, Arnob") - - def initializeTimeHistory(self, resetFromDOF=True): - """ - Push necessary information into time history arrays - """ - for ci in range(self.nc): - self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] - for k in range(self.nStages): - self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] - - def updateTimeHistory(self, resetFromDOF=False): - """ - assumes successful step has been taken - """ - - self.t = self.tLast + self.dt - for ci in range(self.nc): - self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] - for k in range(self.nStages): - self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] - self.lstage = 0 - self.dtLast = self.dt - self.tLast = self.t - - def generateSubsteps(self, tList): - """ - create list of substeps over time values given in tList. These correspond to stages - """ - self.substeps = [] - tLast = self.tLast - for t in tList: - dttmp = t - tLast - self.substeps.extend([tLast + dttmp for i in range(self.nStages)]) - tLast = t - - def resetOrder(self, order): - """ - initialize data structures for stage updges - """ - self.timeOrder = order # order of approximation - self.nStages = order # number of stages total - self.lstage = 0 # last stage completed - # storage vectors - # per component stage values, list with array at each stage - self.u_dof_stage = {} - for ci in range(self.nc): - if ('m', ci) in self.transport.q: - self.u_dof_stage[ci] = [] - for k in range(self.nStages + 1): - self.u_dof_stage[ci].append(self.transport.u[ci].dof.copy()) - self.substeps = [self.t for i in range(self.nStages)] - - def setFromOptions(self, nOptions): - """ - allow classes to set various numerical parameters - """ - if 'runCFL' in dir(nOptions): - self.runCFL = nOptions.runCFL - flags = ['timeOrder'] - for flag in flags: - if flag in dir(nOptions): - val = getattr(nOptions, flag) - setattr(self, flag, val) - if flag == 'timeOrder': - self.resetOrder(self.timeOrder) - - - -class Coefficients(proteus.TransportCoefficients.TC_base): - """ - version of Re where element material type id's used in evals - """ - from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2 - from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchten_sd_het - def __init__(self, - nd, - Ksw_types, - vgm_n_types, - vgm_alpha_types, - thetaR_types, - thetaSR_types, - gravity, - density, - beta, - diagonal_conductivity=True, - getSeepageFace=None, - # FOR EDGE BASED EV - STABILIZATION_TYPE=0, - ENTROPY_TYPE=2, # logarithmic - LUMPED_MASS_MATRIX=False, - MONOLITHIC=True, - FCT=True, - num_fct_iter=1, - # FOR ENTROPY VISCOSITY - cE=1.0, - uL=0.0, - uR=1.0, - # FOR ARTIFICIAL COMPRESSION - cK=1.0, - # OUTPUT quantDOFs - outputQuantDOFs=False, ): - self.anb_seepage_flux= 0.00 - #self.anb_seepage_flux_n =0.0 - variableNames=['pressure_head'] - nc=1 - mass={0:{0:'nonlinear'}} - advection={0:{0:'nonlinear'}} - diffusion={0:{0:{0:'nonlinear'}}} - potential={0:{0:'u'}} - reaction={0:{0:'linear'}} - hamiltonian={} - self.getSeepageFace=getSeepageFace - self.gravity=gravity - self.rho = density - self.beta=beta - self.vgm_n_types = vgm_n_types - self.vgm_alpha_types = vgm_alpha_types - self.thetaR_types = thetaR_types - self.thetaSR_types = thetaSR_types - self.elementMaterialTypes = None - self.exteriorElementBoundaryTypes = None - self.materialTypes_q = None - self.materialTypes_ebq = None - self.materialTypes_ebqe = None - self.nd = nd - self.nMaterialTypes = len(thetaR_types) - self.q = {}; self.ebqe = {}; self.ebq = {}; self.ebq_global={} - #try to allow some flexibility in input of permeability/conductivity tensor - self.diagonal_conductivity = diagonal_conductivity - self.Ksw_types_in = Ksw_types - if self.diagonal_conductivity: - sparseDiffusionTensors = {(0,0):(np.arange(self.nd+1,dtype='i'), - np.arange(self.nd,dtype='i'))} - - assert len(Ksw_types.shape) in [1,2], "if diagonal conductivity true then Ksw_types scalar or vector of diagonal entries" - #allow scalar input Ks - if len(Ksw_types.shape)==1: - self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd),'d') - for I in range(self.nd): - self.Ksw_types[:,I] = Ksw_types - else: - self.Ksw_types = Ksw_types - else: #full - sparseDiffusionTensors = {(0,0):(np.arange(self.nd**2+1,step=self.nd,dtype='i'), - np.array([list(range(self.nd)) for row in range(self.nd)],dtype='i'))} - assert len(Ksw_types.shape) in [1,2], "if full tensor conductivity true then Ksw_types scalar or 'flattened' row-major representation of entries" - if len(Ksw_types.shape)==1: - self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd**2),'d') - for I in range(self.nd): - self.Ksw_types[:,I*self.nd+I] = Ksw_types - else: - assert Ksw_types.shape[1] == self.nd**2 - self.Ksw_types = Ksw_types - # EDGE BASED (AND ENTROPY) VISCOSITY - self.LUMPED_MASS_MATRIX = LUMPED_MASS_MATRIX - self.MONOLITHIC = MONOLITHIC - self.STABILIZATION_TYPE = STABILIZATION_TYPE - self.ENTROPY_TYPE = ENTROPY_TYPE - self.FCT = FCT - self.num_fct_iter=num_fct_iter - self.uL = uL - self.uR = uR - self.cK = cK - self.forceStrongConditions = True - self.cE = cE - self.outputQuantDOFs = outputQuantDOFs - TC_base.__init__(self, - nc, - mass, - advection, - diffusion, - potential, - reaction, - hamiltonian, - variableNames, - sparseDiffusionTensors = sparseDiffusionTensors, - useSparseDiffusion = True) - - def initializeMesh(self,mesh): - from proteus.SubsurfaceTransportCoefficients import BlockHeterogeneousCoefficients - self.elementMaterialTypes,self.exteriorElementBoundaryTypes,self.elementBoundaryTypes = BlockHeterogeneousCoefficients(mesh).initializeMaterialTypes() - #want element boundary material types for evaluating heterogeneity - #not boundary conditions - self.isSeepageFace = np.zeros((mesh.nExteriorElementBoundaries_global),'i') - if self.getSeepageFace != None: - for ebNE in range(mesh.nExteriorElementBoundaries_global): - #mwf missing ebNE-->ebN? - ebN = mesh.exteriorElementBoundariesArray[ebNE] - #print "eb flag",mesh.elementBoundaryMaterialTypes[ebN] - #print("Hi, Arnob") - #print self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) - self.isSeepageFace[ebNE] = self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) - #print (self.isSeepageFace) - def initializeElementQuadrature(self,t,cq): - self.materialTypes_q = self.elementMaterialTypes - self.q_shape = cq[('u',0)].shape - #self.anb_seepage_flux= anb_seepage_flux - #print("The seepage is ", anb_seepage_flux) -# cq['Ks'] = np.zeros(self.q_shape,'d') -# for k in range(self.q_shape[1]): -# cq['Ks'][:,k] = self.Ksw_types[self.elementMaterialTypes,0] - self.q[('vol_frac',0)] = np.zeros(self.q_shape,'d') - def initializeElementBoundaryQuadrature(self,t,cebq,cebq_global): - self.materialTypes_ebq = np.zeros(cebq[('u',0)].shape[0:2],'i') - self.ebq_shape = cebq[('u',0)].shape - for ebN_local in range(self.ebq_shape[1]): - self.materialTypes_ebq[:,ebN_local] = self.elementMaterialTypes - self.ebq[('vol_frac',0)] = np.zeros(self.ebq_shape,'d') - - def initializeGlobalExteriorElementBoundaryQuadrature(self,t,cebqe): - self.materialTypes_ebqe = self.exteriorElementBoundaryTypes - self.ebqe_shape = cebqe[('u',0)].shape - self.ebqe[('vol_frac',0)] = np.zeros(self.ebqe_shape,'d') - # - - - def evaluate(self,t,c): - if c[('u',0)].shape == self.q_shape: - materialTypes = self.materialTypes_q - vol_frac = self.q[('vol_frac',0)] - elif c[('u',0)].shape == self.ebqe_shape: - materialTypes = self.materialTypes_ebqe - vol_frac = self.ebqe[('vol_frac',0)] - elif c[('u',0)].shape == self.ebq_shape: - materialTypes = self.materialTypes_ebq - vol_frac = self.ebq[('vol_frac',0)] - else: - assert False, "no materialType found to match c[('u',0)].shape= %s " % c[('u',0)].shape - self.conservativeHeadRichardsMualemVanGenuchten_sd_het(self.sdInfo[(0,0)][0], - self.sdInfo[(0,0)][1], - materialTypes, - self.rho, - self.beta, - self.gravity, - self.vgm_alpha_types, - self.vgm_n_types, - self.thetaR_types, - self.thetaSR_types, - self.Ksw_types, - c[('u',0)], - c[('m',0)], - c[('dm',0,0)], - c[('f',0)], - c[('df',0,0)], - c[('a',0,0)], - c[('da',0,0,0)], - vol_frac) - # print "Picard---------------------------------------------------------------" - # c[('df',0,0)][:] = 0.0 - # c[('da',0,0,0)][:] = 0.0 -# self.conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2(materialTypes, -# self.rho, -# self.beta, -# self.gravity, -# self.vgm_alpha_types, -# self.vgm_n_types, -# self.thetaR_types, -# self.thetaSR_types, -# self.Ksw_types, -# c[('u',0)], -# c[('m',0)], -# c[('dm',0,0)], -# c[('f',0)], -# c[('df',0,0)], -# c[('a',0,0)], -# c[('da',0,0,0)]) - #mwf debug - if (np.isnan(c[('da',0,0,0)]).any() or - np.isnan(c[('a',0,0)]).any() or - np.isnan(c[('df',0,0)]).any() or - np.isnan(c[('f',0)]).any() or - np.isnan(c[('u',0)]).any() or - np.isnan(c[('m',0)]).any() or - np.isnan(c[('dm',0,0)]).any()): - import pdb - pdb.set_trace() - - def postStep(self, t, firstStep=False): - # #anb_seepage_flux_n[:]= self.anb_seepage_flux - with open('seepage_stab_0', "a") as f: - # f.write("\n Time"+ ",\t" +"Seepage\n") - f.write(repr(t)+ ",\t")# +repr(np.sum(self.LevelModel.anb_seepage_flux_n))) - -class LevelModel(proteus.Transport.OneLevelTransport): - nCalls=0 - def __init__(self, - uDict, - phiDict, - testSpaceDict, - matType, - dofBoundaryConditionsDict, - dofBoundaryConditionsSetterDict, - coefficients, - elementQuadrature, - elementBoundaryQuadrature, - fluxBoundaryConditionsDict=None, - advectiveFluxBoundaryConditionsSetterDict=None, - diffusiveFluxBoundaryConditionsSetterDictDict=None, - stressTraceBoundaryConditionsSetterDict=None, - stabilization=None, - shockCapturing=None, - conservativeFluxDict=None, - numericalFluxType=None, - TimeIntegrationClass=None, - massLumping=False, - reactionLumping=False, - options=None, - name='defaultName', - reuse_trial_and_test_quadrature=True, - sd = True, - movingDomain=False, - bdyNullSpace=False): - self.bdyNullSpace=bdyNullSpace - # - #set the objects describing the method and boundary conditions - # - self.movingDomain=movingDomain - self.tLast_mesh=None - # - self.name=name - self.sd=sd - self.Hess=False - self.lowmem=True - self.timeTerm=True#allow turning off the time derivative - #self.lowmem=False - self.testIsTrial=True - self.phiTrialIsTrial=True - self.u = uDict - self.ua = {}#analytical solutions - self.phi = phiDict - self.dphi={} - self.matType = matType - #mwf try to reuse test and trial information across components if spaces are the same - self.reuse_test_trial_quadrature = reuse_trial_and_test_quadrature#True#False - if self.reuse_test_trial_quadrature: - for ci in range(1,coefficients.nc): - assert self.u[ci].femSpace.__class__.__name__ == self.u[0].femSpace.__class__.__name__, "to reuse_test_trial_quad all femSpaces must be the same!" - self.u_dof_old = None - ## Simplicial Mesh - self.mesh = self.u[0].femSpace.mesh #assume the same mesh for all components for now - self.testSpace = testSpaceDict - self.dirichletConditions = dofBoundaryConditionsDict - self.dirichletNodeSetList=None #explicit Dirichlet conditions for now, no Dirichlet BC constraints - self.coefficients = coefficients - self.coefficients.initializeMesh(self.mesh) - self.nc = self.coefficients.nc - self.stabilization = stabilization - self.shockCapturing = shockCapturing - self.conservativeFlux = conservativeFluxDict #no velocity post-processing for now - self.fluxBoundaryConditions=fluxBoundaryConditionsDict - self.advectiveFluxBoundaryConditionsSetterDict=advectiveFluxBoundaryConditionsSetterDict - self.diffusiveFluxBoundaryConditionsSetterDictDict = diffusiveFluxBoundaryConditionsSetterDictDict - #determine whether the stabilization term is nonlinear - self.stabilizationIsNonlinear = False - #cek come back - if self.stabilization != None: - for ci in range(self.nc): - if ci in coefficients.mass: - for flag in list(coefficients.mass[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.advection: - for flag in list(coefficients.advection[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.diffusion: - for diffusionDict in list(coefficients.diffusion[ci].values()): - for flag in list(diffusionDict.values()): - if flag != 'constant': - self.stabilizationIsNonlinear=True - if ci in coefficients.potential: - for flag in list(coefficients.potential[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.reaction: - for flag in list(coefficients.reaction[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.hamiltonian: - for flag in list(coefficients.hamiltonian[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - #determine if we need element boundary storage - self.elementBoundaryIntegrals = {} - for ci in range(self.nc): - self.elementBoundaryIntegrals[ci] = ((self.conservativeFlux != None) or - (numericalFluxType != None) or - (self.fluxBoundaryConditions[ci] == 'outFlow') or - (self.fluxBoundaryConditions[ci] == 'mixedFlow') or - (self.fluxBoundaryConditions[ci] == 'setFlow')) - # - #calculate some dimensions - # - self.nSpace_global = self.u[0].femSpace.nSpace_global #assume same space dim for all variables - self.nDOF_trial_element = [u_j.femSpace.max_nDOF_element for u_j in list(self.u.values())] - self.nDOF_phi_trial_element = [phi_k.femSpace.max_nDOF_element for phi_k in list(self.phi.values())] - self.n_phi_ip_element = [phi_k.femSpace.referenceFiniteElement.interpolationConditions.nQuadraturePoints for phi_k in list(self.phi.values())] - self.nDOF_test_element = [femSpace.max_nDOF_element for femSpace in list(self.testSpace.values())] - self.nFreeDOF_global = [dc.nFreeDOF_global for dc in list(self.dirichletConditions.values())] - self.nVDOF_element = sum(self.nDOF_trial_element) - self.nFreeVDOF_global = sum(self.nFreeDOF_global) - # - NonlinearEquation.__init__(self,self.nFreeVDOF_global) - # - #build the quadrature point dictionaries from the input (this - #is just for convenience so that the input doesn't have to be - #complete) - # - elementQuadratureDict={} - elemQuadIsDict = isinstance(elementQuadrature,dict) - if elemQuadIsDict: #set terms manually - for I in self.coefficients.elementIntegralKeys: - if I in elementQuadrature: - elementQuadratureDict[I] = elementQuadrature[I] - - else: - elementQuadratureDict[I] = elementQuadrature['default'] - else: - for I in self.coefficients.elementIntegralKeys: - elementQuadratureDict[I] = elementQuadrature - if self.stabilization != None: - for I in self.coefficients.elementIntegralKeys: - if elemQuadIsDict: - if I in elementQuadrature: - elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature[I] - else: - elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature['default'] - else: - elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature - if self.shockCapturing != None: - for ci in self.shockCapturing.components: - if elemQuadIsDict: - if ('numDiff',ci,ci) in elementQuadrature: - elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature[('numDiff',ci,ci)] - #print("Hi, Arnob1") - #print(anb_seepage_flux) - else: - elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature['default'] - #print("Hi, Arnob2") - #print(anb_seepage_flux) - else: - elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature - print("Hi, Arnob3") - #print(anb_seepage_flux) - if massLumping: - for ci in list(self.coefficients.mass.keys()): - elementQuadratureDict[('m',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - print("Hi, Arnob4") - #print(anb_seepage_flux) - for I in self.coefficients.elementIntegralKeys: - elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - print("Hi, Arnob5") - #print(anb_seepage_flux) - if reactionLumping: - for ci in list(self.coefficients.mass.keys()): - elementQuadratureDict[('r',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - print("Hi, Arnob6") - #print(anb_seepage_flux) - for I in self.coefficients.elementIntegralKeys: - elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - print("Hi, Arnob7") - #print(anb_seepage_flux) - elementBoundaryQuadratureDict={} - if isinstance(elementBoundaryQuadrature,dict): #set terms manually - for I in self.coefficients.elementBoundaryIntegralKeys: - if I in elementBoundaryQuadrature: - elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature[I] - print("Hi, Arnob8") - #print(anb_seepage_flux) - else: - elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature['default'] - #print("Hi, Arnob9") - #print(anb_seepage_flux) - else: - for I in self.coefficients.elementBoundaryIntegralKeys: - elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature - print("Hi, Arnob10") - #print(anb_seepage_flux) - # - # find the union of all element quadrature points and - # build a quadrature rule for each integral that has a - # weight at each point in the union - #mwf include tag telling me which indices are which quadrature rule? - (self.elementQuadraturePoints,self.elementQuadratureWeights, - self.elementQuadratureRuleIndeces) = Quadrature.buildUnion(elementQuadratureDict) - self.nQuadraturePoints_element = self.elementQuadraturePoints.shape[0] - self.nQuadraturePoints_global = self.nQuadraturePoints_element*self.mesh.nElements_global - # - #Repeat the same thing for the element boundary quadrature - # - (self.elementBoundaryQuadraturePoints, - self.elementBoundaryQuadratureWeights, - self.elementBoundaryQuadratureRuleIndeces) = Quadrature.buildUnion(elementBoundaryQuadratureDict) - self.nElementBoundaryQuadraturePoints_elementBoundary = self.elementBoundaryQuadraturePoints.shape[0] - self.nElementBoundaryQuadraturePoints_global = (self.mesh.nElements_global* - self.mesh.nElementBoundaries_element* - self.nElementBoundaryQuadraturePoints_elementBoundary) -# if isinstance(self.u[0].femSpace,C0_AffineLinearOnSimplexWithNodalBasis): -# print self.nQuadraturePoints_element -# if self.nSpace_global == 3: -# assert(self.nQuadraturePoints_element == 5) -# elif self.nSpace_global == 2: -# assert(self.nQuadraturePoints_element == 6) -# elif self.nSpace_global == 1: -# assert(self.nQuadraturePoints_element == 3) -# -# print self.nElementBoundaryQuadraturePoints_elementBoundary -# if self.nSpace_global == 3: -# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) -# elif self.nSpace_global == 2: -# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) -# elif self.nSpace_global == 1: -# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 1) - - # - #storage dictionaries - self.scalars_element = set() - # - #simplified allocations for test==trial and also check if space is mixed or not - # - self.q={} - self.ebq={} - self.ebq_global={} - self.ebqe={} - self.phi_ip={} - self.edge_based_cfl = np.zeros(self.u[0].dof.shape)+100 - #mesh - #self.q['x'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,3),'d') - self.q[('dV_u', 0)] = (old_div(1.0, self.mesh.nElements_global)) * np.ones((self.mesh.nElements_global, self.nQuadraturePoints_element), 'd') - self.ebqe['x'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,3),'d') - self.q[('u',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') - self.q[('grad(u)',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') - self.q['velocity'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') - self.q[('m',0)] = self.q[('u',0)].copy() - self.q[('mt',0)] = self.q[('u',0)].copy() - self.q[('m_last',0)] = self.q[('u',0)].copy() - self.q[('m_tmp',0)] = self.q[('u',0)].copy() - self.q[('cfl',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') - self.q[('numDiff',0,0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') - self.ebqe[('u',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.ebqe[('grad(u)',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') - self.ebqe['velocity'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') - self.ebqe[('advectiveFlux_bc_flag',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'i') - self.ebqe[('advectiveFlux_bc',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.ebqe[('advectiveFlux',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.ebqe[('penalty')] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.points_elementBoundaryQuadrature= set() - self.scalars_elementBoundaryQuadrature= set([('u',ci) for ci in range(self.nc)]) - self.vectors_elementBoundaryQuadrature= set() - self.tensors_elementBoundaryQuadrature= set() - self.inflowBoundaryBC = {} - self.inflowBoundaryBC_values = {} - self.inflowFlux = {} - for cj in range(self.nc): - self.inflowBoundaryBC[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,),'i') - self.inflowBoundaryBC_values[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nDOF_trial_element[cj]),'d') - self.inflowFlux[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.internalNodes = set(range(self.mesh.nNodes_global)) - #identify the internal nodes this is ought to be in mesh - ##\todo move this to mesh - for ebNE in range(self.mesh.nExteriorElementBoundaries_global): - ebN = self.mesh.exteriorElementBoundariesArray[ebNE] - eN_global = self.mesh.elementBoundaryElementsArray[ebN,0] - ebN_element = self.mesh.elementBoundaryLocalElementBoundariesArray[ebN,0] - for i in range(self.mesh.nNodes_element): - if i != ebN_element: - I = self.mesh.elementNodesArray[eN_global,i] - self.internalNodes -= set([I]) - self.nNodes_internal = len(self.internalNodes) - self.internalNodesArray=np.zeros((self.nNodes_internal,),'i') - for nI,n in enumerate(self.internalNodes): - self.internalNodesArray[nI]=n - # - del self.internalNodes - self.internalNodes = None - logEvent("Updating local to global mappings",2) - self.updateLocal2Global() - logEvent("Building time integration object",2) - logEvent(memory("inflowBC, internalNodes,updateLocal2Global","OneLevelTransport"),level=4) - #mwf for interpolating subgrid error for gradients etc - if self.stabilization and self.stabilization.usesGradientStabilization: - self.timeIntegration = TimeIntegrationClass(self,integrateInterpolationPoints=True) - else: - self.timeIntegration = TimeIntegrationClass(self) - - if options != None: - self.timeIntegration.setFromOptions(options) - logEvent(memory("TimeIntegration","OneLevelTransport"),level=4) - logEvent("Calculating numerical quadrature formulas",2) - self.calculateQuadrature() - #lay out components/equations contiguously for now - self.offset = [0] - for ci in range(1,self.nc): - self.offset += [self.offset[ci-1]+self.nFreeDOF_global[ci-1]] - self.stride = [1 for ci in range(self.nc)] - #use contiguous layout of components for parallel, requires weak DBC's - # mql. Some ASSERTS to restrict the combination of the methods - if self.coefficients.STABILIZATION_TYPE > 0: - pass - #assert self.timeIntegration.isSSP == True, "If STABILIZATION_TYPE>0, use RKEV timeIntegration within VOF model" - #cond = 'levelNonlinearSolver' in dir(options) and (options.levelNonlinearSolver == - # ExplicitLumpedMassMatrixForRichards or options.levelNonlinearSolver == ExplicitConsistentMassMatrixForRichards) - #assert cond, "If STABILIZATION_TYPE>0, use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards or ExplicitConsistentMassMatrixForRichards" - try: - if 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards: - assert self.coefficients.LUMPED_MASS_MATRIX, "If levelNonlinearSolver=ExplicitLumpedMassMatrix, use LUMPED_MASS_MATRIX=True" - except: - pass - if self.coefficients.LUMPED_MASS_MATRIX == True: - cond = self.coefficients.STABILIZATION_TYPE == 2 - assert cond, "Use lumped mass matrix just with: STABILIZATION_TYPE=2 (smoothness based stab.)" - cond = 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards - assert cond, "Use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards when the mass matrix is lumped" - - ################################################################# - ####################ARNOB_FCT_EDIT############################### - ################################################################# - - if self.coefficients.LUMPED_MASS_MATRIX == False: - cond = self.coefficients.STABILIZATION_TYPE == 2 - assert cond, "Use lumped mass matrix just with: STABILIZATION_TYPE=2 (smoothness based stab.)" - cond = 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == Newton - #assert cond, "Use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards when the mass matrix is lumped" - - - - - - if self.coefficients.FCT == True: - cond = self.coefficients.STABILIZATION_TYPE > 0, "Use FCT just with STABILIZATION_TYPE>0; i.e., edge based stabilization" - # END OF ASSERTS - - # cek adding empty data member for low order numerical viscosity structures here for now - self.ML = None # lumped mass matrix - self.MC_global = None # consistent mass matrix - self.cterm_global = None - self.cterm_transpose_global = None - # dL_global and dC_global are not the full matrices but just the CSR arrays containing the non zero entries - self.residualComputed=False #TMP - self.dLow= None - self.fluxMatrix = None - self.uDotLow = None - self.uLow = None - self.dt_times_dC_minus_dL = None - self.min_s_bc = None - self.max_s_bc = None - # Aux quantity at DOFs to be filled by optimized code (MQL) - self.quantDOFs = np.zeros(self.u[0].dof.shape, 'd') - self.sLow = np.zeros(self.u[0].dof.shape, 'd') - self.sHigh = np.zeros(self.u[0].dof.shape, 'd') - self.sn = np.zeros(self.u[0].dof.shape, 'd') - self.anb_seepage_flux_n = np.zeros(self.u[0].dof.shape, 'd') - comm = Comm.get() - self.comm=comm - if comm.size() > 1: - assert numericalFluxType != None and numericalFluxType.useWeakDirichletConditions,"You must use a numerical flux to apply weak boundary conditions for parallel runs" - self.offset = [0] - for ci in range(1,self.nc): - self.offset += [ci] - self.stride = [self.nc for ci in range(self.nc)] - # - logEvent(memory("stride+offset","OneLevelTransport"),level=4) - - - if numericalFluxType != None: - if options is None or options.periodicDirichletConditions is None: - self.numericalFlux = numericalFluxType(self, - dofBoundaryConditionsSetterDict, - advectiveFluxBoundaryConditionsSetterDict, - diffusiveFluxBoundaryConditionsSetterDictDict) - else: - self.numericalFlux = numericalFluxType(self, - dofBoundaryConditionsSetterDict, - advectiveFluxBoundaryConditionsSetterDict, - diffusiveFluxBoundaryConditionsSetterDictDict, - options.periodicDirichletConditions) - else: - self.numericalFlux = None - #set penalty terms - #cek todo move into numerical flux initialization - if 'penalty' in self.ebq_global: - for ebN in range(self.mesh.nElementBoundaries_global): - for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): - self.ebq_global['penalty'][ebN,k] = old_div(self.numericalFlux.penalty_constant,(self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power)) - #penalty term - #cek move to Numerical flux initialization - if 'penalty' in self.ebqe: - for ebNE in range(self.mesh.nExteriorElementBoundaries_global): - ebN = self.mesh.exteriorElementBoundariesArray[ebNE] - for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): - self.ebqe['penalty'][ebNE,k] = old_div(self.numericalFlux.penalty_constant,self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power) - logEvent(memory("numericalFlux","OneLevelTransport"),level=4) - self.elementEffectiveDiametersArray = self.mesh.elementInnerDiametersArray - #use post processing tools to get conservative fluxes, None by default - from proteus import PostProcessingTools - self.velocityPostProcessor = PostProcessingTools.VelocityPostProcessingChooser(self) - logEvent(memory("velocity postprocessor","OneLevelTransport"),level=4) - #helper for writing out data storage - from proteus import Archiver - self.elementQuadratureDictionaryWriter = Archiver.XdmfWriter() - self.elementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() - self.exteriorElementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() - #TODO get rid of this - for ci,fbcObject in list(self.fluxBoundaryConditionsObjectsDict.items()): - self.ebqe[('advectiveFlux_bc_flag',ci)] = np.zeros(self.ebqe[('advectiveFlux_bc',ci)].shape,'i') - for t,g in list(fbcObject.advectiveFluxBoundaryConditionsDict.items()): - if ci in self.coefficients.advection: - self.ebqe[('advectiveFlux_bc',ci)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) - self.ebqe[('advectiveFlux_bc_flag',ci)][t[0],t[1]] = 1 - - if hasattr(self.numericalFlux,'setDirichletValues'): - self.numericalFlux.setDirichletValues(self.ebqe) - if not hasattr(self.numericalFlux,'isDOFBoundary'): - self.numericalFlux.isDOFBoundary = {0:np.zeros(self.ebqe[('u',0)].shape,'i')} - if not hasattr(self.numericalFlux,'ebqe'): - self.numericalFlux.ebqe = {('u',0):np.zeros(self.ebqe[('u',0)].shape,'d')} - #TODO how to handle redistancing calls for calculateCoefficients,calculateElementResidual etc - self.globalResidualDummy = None - compKernelFlag=0 - self.delta_x_ij=None - self.richards = cRichards_base(self.nSpace_global, - self.nQuadraturePoints_element, - self.u[0].femSpace.elementMaps.localFunctionSpace.dim, - self.u[0].femSpace.referenceFiniteElement.localFunctionSpace.dim, - self.testSpace[0].referenceFiniteElement.localFunctionSpace.dim, - self.nElementBoundaryQuadraturePoints_elementBoundary, - compKernelFlag) - if self.movingDomain: - self.MOVING_DOMAIN=1.0 - else: - self.MOVING_DOMAIN=0.0 - #cek hack - self.movingDomain=False - self.MOVING_DOMAIN=0.0 - if self.mesh.nodeVelocityArray is None: - self.mesh.nodeVelocityArray = np.zeros(self.mesh.nodeArray.shape,'d') - self.forceStrongConditions=True - self.dirichletConditionsForceDOF = {} - if self.forceStrongConditions: - for cj in range(self.nc): - self.dirichletConditionsForceDOF[cj] = DOFBoundaryConditions(self.u[cj].femSpace,dofBoundaryConditionsSetterDict[cj],weakDirichletConditions=False) - def FCTStep(self): - import pdb - rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() - limited_solution = np.zeros((len(rowptr) - 1),'d') - #self.u_free_dof_stage_0_l = np.zeros((len(rowptr) - 1),'d') - #self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage], # soln - #fromFreeToGlobal=0 - #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - # self.offset[0], - # self.stride[0], - # self.dirichletConditions[0].global2freeGlobal_global_dofs, - # self.dirichletConditions[0].global2freeGlobal_free_dofs, - # self.u_free_dof_stage_0_l, - # self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage]) - argsDict = cArgumentsDict.ArgumentsDict() - argsDict["bc_mask"] = self.bc_mask - argsDict["NNZ"] = self.nnz - argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs - argsDict["dt"] = self.timeIntegration.dt - argsDict["lumped_mass_matrix"] = self.ML - argsDict["soln"] = self.sn - argsDict["pn"] = self.u[0].dof - argsDict["solH"] = self.sHigh - argsDict["uLow"] = self.sLow - argsDict["uDotLow"] = self.uDotLow - argsDict["limited_solution"] = limited_solution - argsDict["csrRowIndeces_DofLoops"] = rowptr - argsDict["csrColumnOffsets_DofLoops"] = colind - argsDict["MassMatrix"] = MassMatrix - argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL - argsDict["min_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0]) #cek hack just set from physical bounds - argsDict["max_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0] + self.coefficients.thetaSR_types[0]) #cek hack - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - argsDict["MONOLITHIC"] =0#cek hack self.coefficients.MONOLITHIC - argsDict["anb_seepage_flux_n"]= self.anb_seepage_flux_n - #pdb.set_trace() - self.richards.FCTStep(argsDict) - - # self.nnz, # number of non zero entries - # len(rowptr) - 1, # number of DOFs - # self.timeIntegration.dt, - # self.ML, # Lumped mass matrix - # self.sn, - # self.u_dof_old, - # self.sHigh, # high order solution - # self.sLow, - # limited_solution, - # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) - # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) - # MassMatrix, - # self.dt_times_dC_minus_dL, - # self.min_s_bc, - # self.max_s_bc, - # self.coefficients.LUMPED_MASS_MATRIX, - # self.coefficients.MONOLITHIC) - old_dof = self.u[0].dof.copy() - self.invert(limited_solution, self.u[0].dof) - self.timeIntegration.u[:] = self.u[0].dof - #fromFreeToGlobal=1 #direction copying - #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - # self.offset[0], - # self.stride[0], - # self.dirichletConditions[0].global2freeGlobal_global_dofs, - # self.dirichletConditions[0].global2freeGlobal_free_dofs, - # self.u[0].dof, - # limited_solution) - def kth_FCT_step(self): - #import pdb - #pdb.set_trace() - rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() - limitedFlux = np.zeros(self.nnz) - limited_solution = np.zeros((len(rowptr) - 1),'d') - #limited_solution[:] = self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage] - fromFreeToGlobal=0 #direction copying - cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - self.offset[0], - self.stride[0], - self.dirichletConditions[0].global2freeGlobal_global_dofs, - self.dirichletConditions[0].global2freeGlobal_free_dofs, - limited_solution, - self.timeintegration.u_dof_stage[0][self.timeIntegration.lstage]) - - self.richards.kth_FCT_step( - self.timeIntegration.dt, - self.coefficients.num_fct_iter, - self.nnz, # number of non zero entries - len(rowptr) - 1, # number of DOFs - MassMatrix, - self.ML, # Lumped mass matrix - self.u_dof_old, - limited_solution, - self.uDotLow, - self.uLow, - self.dLow, - self.fluxMatrix, - limitedFlux, - rowptr, - colind) - - self.timeIntegration.u[:] = limited_solution - #self.u[0].dof[:] = limited_solution - fromFreeToGlobal=1 #direction copying - cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - self.offset[0], - self.stride[0], - self.dirichletConditions[0].global2freeGlobal_global_dofs, - self.dirichletConditions[0].global2freeGlobal_free_dofs, - self.u[0].dof, - limited_solution) - def calculateCoefficients(self): - pass - def calculateElementResidual(self): - if self.globalResidualDummy != None: - self.getResidual(self.u[0].dof,self.globalResidualDummy) - def getResidual(self,u,r): - import pdb - import copy - """ - Calculate the element residuals and add in to the global residual - """ - cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, - self.jacobian) - if self.u_dof_old is None: - # Pass initial condition to u_dof_old - self.u_dof_old = np.copy(self.u[0].dof) - rowptr, colind, nzval = self.jacobian.getCSRrepresentation() - nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix - r.fill(0.0) - ######################## - ### COMPUTE C MATRIX ### - ######################## - if self.cterm_global is None: - # since we only need cterm_global to persist, we can drop the other self.'s - self.cterm = {} - self.cterm_a = {} - self.cterm_global = {} - self.cterm_transpose = {} - self.cterm_a_transpose = {} - self.cterm_global_transpose = {} - rowptr, colind, nzval = self.jacobian.getCSRrepresentation() - nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix - di = self.q[('grad(u)', 0)].copy() # direction of derivative - # JACOBIANS (FOR ELEMENT TRANSFORMATION) - self.q[('J')] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nSpace_global, - self.nSpace_global), - 'd') - self.q[('inverse(J)')] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nSpace_global, - self.nSpace_global), - 'd') - self.q[('det(J)')] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element), - 'd') - self.u[0].femSpace.elementMaps.getJacobianValues(self.elementQuadraturePoints, - self.q['J'], - self.q['inverse(J)'], - self.q['det(J)']) - self.q['abs(det(J))'] = np.abs(self.q['det(J)']) - # SHAPE FUNCTIONS - self.q[('w', 0)] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nDOF_test_element[0]), - 'd') - self.q[('w*dV_m', 0)] = self.q[('w', 0)].copy() - self.u[0].femSpace.getBasisValues(self.elementQuadraturePoints, self.q[('w', 0)]) - cfemIntegrals.calculateWeightedShape(self.elementQuadratureWeights[('u', 0)], - self.q['abs(det(J))'], - self.q[('w', 0)], - self.q[('w*dV_m', 0)]) - # GRADIENT OF TEST FUNCTIONS - self.q[('grad(w)', 0)] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nDOF_test_element[0], - self.nSpace_global), - 'd') - self.u[0].femSpace.getBasisGradientValues(self.elementQuadraturePoints, - self.q['inverse(J)'], - self.q[('grad(w)', 0)]) - self.q[('grad(w)*dV_f', 0)] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nDOF_test_element[0], - self.nSpace_global), - 'd') - cfemIntegrals.calculateWeightedShapeGradients(self.elementQuadratureWeights[('u', 0)], - self.q['abs(det(J))'], - self.q[('grad(w)', 0)], - self.q[('grad(w)*dV_f', 0)]) - ########################## - ### LUMPED MASS MATRIX ### - ########################## - # assume a linear mass term - dm = np.ones(self.q[('u', 0)].shape, 'd') - elementMassMatrix = np.zeros((self.mesh.nElements_global, - self.nDOF_test_element[0], - self.nDOF_trial_element[0]), 'd') - cfemIntegrals.updateMassJacobian_weak_lowmem(dm, - self.q[('w', 0)], - self.q[('w*dV_m', 0)], - elementMassMatrix) - self.MC_a = nzval.copy() - self.MC_global = SparseMat(self.nFreeDOF_global[0], - self.nFreeDOF_global[0], - nnz, - self.MC_a, - colind, - rowptr) - cfemIntegrals.zeroJacobian_CSR(self.nnz, self.MC_global) - cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.csrRowIndeces[(0, 0)], - self.csrColumnOffsets[(0, 0)], - elementMassMatrix, - self.MC_global) - self.ML = np.zeros((self.nFreeDOF_global[0],), 'd') - for i in range(self.nFreeDOF_global[0]): - self.ML[i] = self.MC_a[rowptr[i]:rowptr[i + 1]].sum() - np.testing.assert_almost_equal(self.ML.sum(), - self.mesh.volume, - err_msg="Trace of lumped mass matrix should be the domain volume", verbose=True) - for d in range(self.nSpace_global): # spatial dimensions - # C matrices - self.cterm[d] = np.zeros((self.mesh.nElements_global, - self.nDOF_test_element[0], - self.nDOF_trial_element[0]), 'd') - self.cterm_a[d] = nzval.copy() - #self.cterm_a[d] = np.zeros(nzval.size) - self.cterm_global[d] = SparseMat(self.nFreeDOF_global[0], - self.nFreeDOF_global[0], - nnz, - self.cterm_a[d], - colind, - rowptr) - cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global[d]) - di[:] = 0.0 - di[..., d] = 1.0 - cfemIntegrals.updateHamiltonianJacobian_weak_lowmem(di, - self.q[('grad(w)*dV_f', 0)], - self.q[('w', 0)], - self.cterm[d]) # int[(di*grad(wj))*wi*dV] - cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.csrRowIndeces[(0, 0)], - self.csrColumnOffsets[(0, 0)], - self.cterm[d], - self.cterm_global[d]) - # C Transpose matrices - self.cterm_transpose[d] = np.zeros((self.mesh.nElements_global, - self.nDOF_test_element[0], - self.nDOF_trial_element[0]), 'd') - self.cterm_a_transpose[d] = nzval.copy() - self.cterm_global_transpose[d] = SparseMat(self.nFreeDOF_global[0], - self.nFreeDOF_global[0], - nnz, - self.cterm_a_transpose[d], - colind, - rowptr) - cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global_transpose[d]) - di[:] = 0.0 - di[..., d] = -1.0 - cfemIntegrals.updateAdvectionJacobian_weak_lowmem(di, - self.q[('w', 0)], - self.q[('grad(w)*dV_f', 0)], - self.cterm_transpose[d]) # -int[(-di*grad(wi))*wj*dV] - cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.csrRowIndeces[(0, 0)], - self.csrColumnOffsets[(0, 0)], - self.cterm_transpose[d], - self.cterm_global_transpose[d]) - - rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() - else: - Cy = np.zeros(Cx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() - else: - Cz = np.zeros(Cx.shape, 'd') - rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() - else: - CTy = np.zeros(CTx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() - else: - CTz = np.zeros(CTx.shape, 'd') - - # This is dummy. I just care about the csr structure of the sparse matrix - self.dLow = np.zeros(Cx.shape, 'd') - self.fluxMatrix = np.zeros(Cx.shape, 'd') - self.dt_times_dC_minus_dL = np.zeros(Cx.shape, 'd') - nFree = len(rowptr)-1 - self.min_s_bc = np.zeros(nFree, 'd') + 1E10 - self.max_s_bc = np.zeros(nFree, 'd') - 1E10 - self.uDotLow = np.zeros(nFree, 'd') - self.uLow = np.zeros(nFree, 'd') - # - # cek end computationa of cterm_global - # - # cek showing mquezada an example of using cterm_global sparse matrix - # calculation y = c*x where x==1 - # direction=0 - #rowptr, colind, c = self.cterm_global[direction].getCSRrepresentation() - #y = np.zeros((self.nFreeDOF_global[0],),'d') - #x = np.ones((self.nFreeDOF_global[0],),'d') - # ij=0 - # for i in range(self.nFreeDOF_global[0]): - # for offset in range(rowptr[i],rowptr[i+1]): - # j = colind[offset] - # y[i] += c[ij]*x[j] - # ij+=1 - #Load the unknowns into the finite element dof - self.timeIntegration.calculateCoefs() - self.timeIntegration.calculateU(u) - self.setUnknowns(self.timeIntegration.u) - #cek can put in logic to skip of BC's don't depend on t or u - #Dirichlet boundary conditions - self.numericalFlux.setDirichletValues(self.ebqe) - #flux boundary conditions - #cek hack, just using advective flux for flux BC for now - for t,g in list(self.fluxBoundaryConditionsObjectsDict[0].advectiveFluxBoundaryConditionsDict.items()): - self.ebqe[('advectiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) - self.ebqe[('advectiveFlux_bc_flag',0)][t[0],t[1]] = 1 - # for t,g in self.fluxBoundaryConditionsObjectsDict[0].diffusiveFluxBoundaryConditionsDict.iteritems(): - # self.ebqe[('diffusiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) - # self.ebqe[('diffusiveFlux_bc_flag',0)][t[0],t[1]] = 1 - #self.shockCapturing.lag=True - if self.forceStrongConditions: - self.bc_mask = np.ones_like(self.u[0].dof) - for cj in range(len(self.dirichletConditionsForceDOF)): - for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): - self.u[cj].dof[dofN] = g(self.dirichletConditionsForceDOF[cj].DOFBoundaryPointDict[dofN],self.timeIntegration.t) - self.u_dof_old[dofN] = self.u[cj].dof[dofN] - self.bc_mask[dofN] = 0.0 - degree_polynomial = 1 - try: - degree_polynomial = self.u[0].femSpace.order - except: - pass - - argsDict = cArgumentsDict.ArgumentsDict() - argsDict["bc_mask"] = self.bc_mask - argsDict["dt"] = self.timeIntegration.dt - argsDict["Theta"] = 1.0 - argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi - argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi - argsDict["mesh_dof"] = self.mesh.nodeArray - argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray - argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN - argsDict["mesh_l2g"] = self.mesh.elementNodesArray - argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] - argsDict["u_trial_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi - argsDict["u_test_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi - argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace - argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace - argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] - argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals - argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians - argsDict["nElements_global"] = self.mesh.nElements_global - argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] - argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, - argsDict["isSeepageFace"] = self.coefficients.isSeepageFace - argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] - argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] - argsDict["rho"] = self.coefficients.rho - argsDict["beta"] = self.coefficients.beta - argsDict["gravity"] = self.coefficients.gravity - argsDict["alpha"] = self.coefficients.vgm_alpha_types - argsDict["n"] = self.coefficients.vgm_n_types - argsDict["thetaR"] = self.coefficients.thetaR_types - argsDict["thetaSR"] = self.coefficients.thetaSR_types - argsDict["KWs"] = self.coefficients.Ksw_types - argsDict["useMetrics"] = 0.0 - argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf - argsDict["lag_shockCapturing"] = 0 - argsDict["shockCapturingDiffusion"] = 0.0 - argsDict["sc_uref"] = 0.0 - argsDict["sc_alpha"] = 0.0 - argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g - argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] - argsDict["elementDiameter"] = self.mesh.elementDiametersArray - argsDict["degree_polynomial"] = degree_polynomial - argsDict["u_dof"] = self.u[0].dof - argsDict["u_dof_old"] = self.u_dof_old - argsDict["velocity"] = self.q['velocity'] - argsDict["q_m"] = self.timeIntegration.m_tmp[0] - argsDict["q_u"] = self.q[('u',0)] - argsDict["q_dV"] = self.q[('dV_u',0)] - argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] - argsDict["cfl"] = self.q[('cfl',0)] - argsDict["q_numDiff_u"] = self.q[('cfl',0)] - argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] - argsDict["offset_u"] = self.offset[0] - argsDict["stride_u"] = self.stride[0] - argsDict["globalResidual"] = r - argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global - argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray - argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray - argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray - argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] - argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] - argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] - argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] - argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] - argsDict["ebqe_phi"] = self.ebqe[('u',0)] - argsDict["epsFact"] = 0.0 - argsDict["ebqe_u"] = self.ebqe[('u',0)] - argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] - argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE - # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION - argsDict["cE"] = self.coefficients.cE - argsDict["cK"] = self.coefficients.cK - # PARAMETERS FOR LOG BASED ENTROPY FUNCTION - argsDict["uL"] = self.coefficients.uL - argsDict["uR"] = self.coefficients.uR - # PARAMETERS FOR EDGE VISCOSITY - argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs - argsDict["NNZ"] = self.nnz - argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern - argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) - argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) - argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms - argsDict["globalJacobian"] = self.jacobian.getCSRrepresentation()[2] - # C matrices - argsDict["Cx"] = Cx - argsDict["Cy"] = Cy - argsDict["Cz"] = Cz - argsDict["CTx"] = CTx - argsDict["CTy"] = CTy - argsDict["CTz"] = CTz - argsDict["ML"] = self.ML - argsDict["delta_x_ij"] = self.delta_x_ij - # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE - argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE - # FLUX CORRECTED TRANSPORT - argsDict["dLow"] = self.dLow - argsDict["fluxMatrix"] = self.fluxMatrix - argsDict["uDotLow"] = self.uDotLow - argsDict["uLow"] = self.uLow - argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL - argsDict["min_s_bc"] = self.min_s_bc - argsDict["max_s_bc"] = self.max_s_bc - argsDict["quantDOFs"] = self.quantDOFs - argsDict["sLow"] = self.sLow - argsDict["sn"] = self.sn - argsDict["anb_seepage_flux_n"]= self.anb_seepage_flux_n -###################################################################################### - argsDict["pn"] = self.u[0].dof - argsDict["solH"] = self.sHigh - - rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() - argsDict["MassMatrix"] = MassMatrix - argsDict["solH"] = self.sHigh - -###################################################################################### - argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - #print(anb_seepage_flux) - #argsDict["anb_seepage_flux_n"] = self.coefficients.anb_seepage_flux_n - #if np.sum(anb_seepage_flux_n)>0: - - #logEvent("Hi, this is Arnob", self.anb_seepage_flux_n[0]) - print("Seepage Flux from Python file", np.sum(self.anb_seepage_flux_n)) - seepage_text_variable= np.sum(self.anb_seepage_flux_n) - - with open('seepage_stab_0',"a" ) as f: - #f.write("\n Time"+ ",\t" +"Seepage\n") - #f.write(repr(self.coefficients.t)+ ",\t" +repr(seepage_text_variable), "\n") - f.write(repr(seepage_text_variable)+ "\n") - if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG - self.calculateResidual = self.richards.calculateResidual - self.calculateJacobian = self.richards.calculateJacobian - else: - self.calculateResidual = self.richards.calculateResidual_entropy_viscosity - self.calculateJacobian = self.richards.calculateMassMatrix - if self.delta_x_ij is None: - self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') - self.calculateResidual(argsDict) - #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] - #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf - #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] - #self.timeIntegration.calculateElementCoefficients(self.q) - if self.forceStrongConditions:# - for cj in range(len(self.dirichletConditionsForceDOF)):# - for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): - r[self.offset[cj]+self.stride[cj]*dofN] = 0 - if self.stabilization: - self.stabilization.accumulateSubgridMassHistory(self.q) - logEvent("Global residual",level=9,data=r) - self.nonlinear_function_evaluations += 1 - if self.globalResidualDummy is None: - self.globalResidualDummy = np.zeros(r.shape,'d') - - #print("Hello from the python file", self.coefficients.anb_seepage_flux) - #logEvent("Hello from the python file", self.coefficients.anb_seepage_flux") - - - - - - def invert(self,u,r): - #u=s - #r=p - import pdb - import copy - """ - Calculate the element residuals and add in to the global residual - """ - self.sHigh[:] = u - rowptr, colind, nzval = self.jacobian.getCSRrepresentation() - nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix - r.fill(0.0) - rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() - else: - Cy = np.zeros(Cx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() - else: - Cz = np.zeros(Cx.shape, 'd') - rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() - else: - CTy = np.zeros(CTx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() - else: - CTz = np.zeros(CTx.shape, 'd') - - # This is dummy. I just care about the csr structure of the sparse matrix - nFree = len(rowptr)-1 - degree_polynomial = 1 - try: - degree_polynomial = self.u[0].femSpace.order - except: - pass - if self.delta_x_ij is None: - self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') - argsDict = cArgumentsDict.ArgumentsDict() - argsDict["dt"] = self.timeIntegration.dt - argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi - argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi - argsDict["mesh_dof"] = self.mesh.nodeArray - argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray - argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN - argsDict["mesh_l2g"] = self.mesh.elementNodesArray - argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] - argsDict["u_trial_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi - argsDict["u_test_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi - argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace - argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace - argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] - argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals - argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians - argsDict["nElements_global"] = self.mesh.nElements_global - argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] - argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, - argsDict["isSeepageFace"] = self.coefficients.isSeepageFace - argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] - argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] - argsDict["rho"] = self.coefficients.rho - argsDict["beta"] = self.coefficients.beta - argsDict["gravity"] = self.coefficients.gravity - argsDict["alpha"] = self.coefficients.vgm_alpha_types - argsDict["n"] = self.coefficients.vgm_n_types - argsDict["thetaR"] = self.coefficients.thetaR_types - argsDict["thetaSR"] = self.coefficients.thetaSR_types - argsDict["KWs"] = self.coefficients.Ksw_types - argsDict["useMetrics"] = 0.0 - argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf - argsDict["lag_shockCapturing"] = 0 - argsDict["shockCapturingDiffusion"] = 0.0 - argsDict["sc_uref"] = 0.0 - argsDict["sc_alpha"] = 0.0 - argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g - argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] - argsDict["elementDiameter"] = self.mesh.elementDiametersArray - argsDict["degree_polynomial"] = degree_polynomial - argsDict["u_dof"] = u#self.u[0].dof - argsDict["u_dof_old"] = self.u[0].dof - argsDict["velocity"] = self.q['velocity'] - argsDict["q_m"] = self.timeIntegration.m_tmp[0] - argsDict["q_u"] = self.q[('u',0)] - argsDict["q_dV"] = self.q[('dV_u',0)] - argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] - argsDict["cfl"] = self.q[('cfl',0)] - argsDict["q_numDiff_u"] = self.q[('cfl',0)] - argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] - argsDict["offset_u"] = self.offset[0] - argsDict["stride_u"] = self.stride[0] - argsDict["globalResidual"] = r - argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global - argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray - argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray - argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray - argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] - argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] - argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] - argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] - argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] - argsDict["ebqe_phi"] = self.ebqe[('u',0)] - argsDict["epsFact"] = 0.0 - argsDict["ebqe_u"] = self.ebqe[('u',0)] - argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] - argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE - # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION - argsDict["cE"] = self.coefficients.cE - argsDict["cK"] = self.coefficients.cK - # PARAMETERS FOR LOG BASED ENTROPY FUNCTION - argsDict["uL"] = self.coefficients.uL - argsDict["uR"] = self.coefficients.uR - # PARAMETERS FOR EDGE VISCOSITY - argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs - argsDict["NNZ"] = self.nnz - argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern - argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) - argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) - argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms - # C matrices - argsDict["Cx"] = Cx - argsDict["Cy"] = Cy - argsDict["Cz"] = Cz - argsDict["CTx"] = CTx - argsDict["CTy"] = CTy - argsDict["CTz"] = CTz - argsDict["ML"] = self.ML - argsDict["delta_x_ij"] = self.delta_x_ij - # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE - argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE - # FLUX CORRECTED TRANSPORT - argsDict["dLow"] = self.dLow - argsDict["fluxMatrix"] = self.fluxMatrix - argsDict["uDotLow"] = self.uDotLow - argsDict["uLow"] = self.uLow - argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL - argsDict["min_s_bc"] = self.min_s_bc - argsDict["max_s_bc"] = self.max_s_bc - argsDict["quantDOFs"] = self.quantDOFs - argsDict["sLow"] = self.sLow - argsDict["sn"] = self.sn - #Arnob trying to print flux - argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - #print("Hi",anb_seepage_flux) - #print("Hi Seepage Flux", self.coefficients.anb_seepage_flux) - - self.richards.invert(argsDict) - # self.timeIntegration.dt, - # self.u[0].femSpace.elementMaps.psi, - # self.u[0].femSpace.elementMaps.grad_psi, - # self.mesh.nodeArray, - # self.mesh.nodeVelocityArray, - # self.MOVING_DOMAIN, - # self.mesh.elementNodesArray, - # self.elementQuadratureWeights[('u',0)], - # self.u[0].femSpace.psi, - # self.u[0].femSpace.grad_psi, - # self.u[0].femSpace.psi, - # self.u[0].femSpace.grad_psi, - # #element boundary - # self.u[0].femSpace.elementMaps.psi_trace, - # self.u[0].femSpace.elementMaps.grad_psi_trace, - # self.elementBoundaryQuadratureWeights[('u',0)], - # self.u[0].femSpace.psi_trace, - # self.u[0].femSpace.grad_psi_trace, - # self.u[0].femSpace.psi_trace, - # self.u[0].femSpace.grad_psi_trace, - # self.u[0].femSpace.elementMaps.boundaryNormals, - # self.u[0].femSpace.elementMaps.boundaryJacobians, - # #physics - # self.mesh.nElements_global, - # self.ebqe['penalty'],#double* ebqe_penalty_ext, - # self.mesh.elementMaterialTypes,#int* elementMaterialTypes, - # self.coefficients.isSeepageFace, - # self.coefficients.sdInfo[(0,0)][0],#int* a_rowptr, - # self.coefficients.sdInfo[(0,0)][1],#int* a_colind, - # self.coefficients.rho,#double rho, - # self.coefficients.beta,#double beta, - # self.coefficients.gravity,#double* gravity, - # self.coefficients.vgm_alpha_types,#double* alpha, - # self.coefficients.vgm_n_types,#double* n, - # self.coefficients.thetaR_types,#double* thetaR, - # self.coefficients.thetaSR_types,#double* thetaSR, - # self.coefficients.Ksw_types,#double* KWs, - # False,#self.coefficients.useMetrics, - # self.timeIntegration.alpha_bdf, - # 0,#self.shockCapturing.lag, - # 0.0,#cek hack self.shockCapturing.shockCapturingFactor, - # 0.0,#self.coefficients.sc_uref, - # 0.0,#self.coefficients.sc_beta, - # self.u[0].femSpace.dofMap.l2g, - # self.l2g[0]['freeGlobal'], - # self.mesh.elementDiametersArray, - # degree_polynomial, - # self.sHigh, - # self.u_dof_old, - # self.q['velocity'],#self.coefficients.q_v, - # self.timeIntegration.m_tmp[0], - # self.q[('u',0)], - # self.timeIntegration.beta_bdf[0], - # self.q[('cfl',0)], - # self.edge_based_cfl, - # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff[0], - # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff_last[0], - # self.offset[0],self.stride[0], - # r, - # self.mesh.nExteriorElementBoundaries_global, - # self.mesh.exteriorElementBoundariesArray, - # self.mesh.elementBoundaryElementsArray, - # self.mesh.elementBoundaryLocalElementBoundariesArray, - # self.ebqe['velocity'],#self.coefficients.ebqe_v, - # self.numericalFlux.isDOFBoundary[0], - # self.numericalFlux.ebqe[('u',0)], - # self.ebqe[('advectiveFlux_bc_flag',0)], - # self.ebqe[('advectiveFlux_bc',0)], - # self.ebqe[('u',0)],#cek hack self.coefficients.ebqe_phi, - # 0.0,#cek hack self.coefficients.epsFact, - # self.ebqe[('u',0)], - # self.ebqe[('advectiveFlux',0)], - # # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION - # self.coefficients.cE, - # self.coefficients.cK, - # # PARAMETERS FOR LOG BASED ENTROPY FUNCTION - # self.coefficients.uL, - # self.coefficients.uR, - # # PARAMETERS FOR EDGE VISCOSITY - # len(rowptr) - 1, # num of DOFs - # len(Cx), # num of non-zero entries in the sparsity pattern - # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) - # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) - # self.csrRowIndeces[(0, 0)], # row indices (convenient for element loops) - # self.csrColumnOffsets[(0, 0)], # column indices (convenient for element loops) - # self.csrColumnOffsets_eb[(0, 0)], # indices for boundary terms - # # C matrices - # Cx, - # Cy, - # Cz, - # CTx, - # CTy, - # CTz, - # self.ML, - # self.delta_x_ij, - # # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - # self.coefficients.LUMPED_MASS_MATRIX, - # self.coefficients.STABILIZATION_TYPE, - # self.coefficients.ENTROPY_TYPE, - # # FLUX CORRECTED TRANSPORT - # self.dLow, - # self.fluxMatrix, - # self.uDotLow, - # self.uLow, - # self.dt_times_dC_minus_dL, - # self.min_s_bc, - # self.max_s_bc, - # self.quantDOFs) - #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] - #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf - #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] - #self.timeIntegration.calculateElementCoefficients(self.q) - #if self.forceStrongConditions:# - # for cj in range(len(self.dirichletConditionsForceDOF)):# - # for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): - # r[self.offset[cj]+self.stride[cj]*dofN] = 0 - #if self.stabilization: - # self.stabilization.accumulateSubgridMassHistory(self.q) - #logEvent("Global residual",level=9,data=r) - #self.nonlinear_function_evaluations += 1 - #if self.globalResidualDummy is None: - # self.globalResidualDummy = numpy.zeros(r.shape,'d') - def postStep(self, t, firstStep=False): - with open('seepage_flux_nnnn', "a") as f: - f.write("\n Time"+ ",\t" +"Seepage\n") - f.write(repr(t)+ ",\t" +repr(self.coefficients.anb_seepage_flux)) - def getJacobian(self,jacobian): - if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG - cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, - jacobian) - degree_polynomial = 1 - try: - degree_polynomial = self.u[0].femSpace.order - except: - pass - if self.delta_x_ij is None: - self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') - argsDict = cArgumentsDict.ArgumentsDict() - argsDict["dt"] = self.timeIntegration.dt - argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi - argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi - argsDict["mesh_dof"] = self.mesh.nodeArray - argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray - argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN - argsDict["mesh_l2g"] = self.mesh.elementNodesArray - argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] - argsDict["u_trial_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi - argsDict["u_test_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi - argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace - argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace - argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] - argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals - argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians - argsDict["nElements_global"] = self.mesh.nElements_global - argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] - argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, - argsDict["isSeepageFace"] = self.coefficients.isSeepageFace - argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] - argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] - argsDict["rho"] = self.coefficients.rho - argsDict["beta"] = self.coefficients.beta - argsDict["gravity"] = self.coefficients.gravity - argsDict["alpha"] = self.coefficients.vgm_alpha_types - argsDict["n"] = self.coefficients.vgm_n_types - argsDict["thetaR"] = self.coefficients.thetaR_types - argsDict["thetaSR"] = self.coefficients.thetaSR_types - argsDict["KWs"] = self.coefficients.Ksw_types - argsDict["useMetrics"] = 0.0 - argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf - argsDict["lag_shockCapturing"] = 0 - argsDict["shockCapturingDiffusion"] = 0.0 - argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g - argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] - argsDict["elementDiameter"] = self.mesh.elementDiametersArray - argsDict["degree_polynomial"] = degree_polynomial - argsDict["u_dof"] = self.u[0].dof - argsDict["velocity"] = self.q['velocity'] - argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] - argsDict["cfl"] = self.q[('cfl',0)] - argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] - argsDict["csrRowIndeces_u_u"] = self.csrRowIndeces[(0,0)] - argsDict["csrColumnOffsets_u_u"] = self.csrColumnOffsets[(0,0)] - argsDict["globalJacobian"] = jacobian.getCSRrepresentation()[2] - argsDict["delta_x_ij"] = self.delta_x_ij - argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global - argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray - argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray - argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray - argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] - argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] - argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] - argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] - argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] - argsDict["csrColumnOffsets_eb_u_u"] = self.csrColumnOffsets_eb[(0,0)] - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - - #arnob trying to calculate flux - #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - #Arnob trying to print flux - #argsDict["anb_seepage_flux"] = self.calculateResidual.anb_seepage_flux - - #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - #print("Hi Seepage Flux", self.coefficients.anb_seepage_flux) - #print("Hi Seepage Flux",anb_seepage_flux) - #print("The seepage is ", anb_seepage_flux) - - - - - self.calculateJacobian(argsDict) - if self.forceStrongConditions: - for dofN in list(self.dirichletConditionsForceDOF[0].DOFBoundaryConditionsDict.keys()): - global_dofN = self.offset[0]+self.stride[0]*dofN - self.nzval[np.where(self.colind == global_dofN)] = 0.0 #column - self.nzval[self.rowptr[global_dofN]:self.rowptr[global_dofN+1]] = 0.0 #row - zeroRow=True - for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]):#row - if (self.colind[i] == global_dofN): - self.nzval[i] = 1.0 - zeroRow = False - if zeroRow: - raise RuntimeError("Jacobian has a zero row because sparse matrix has no diagonal entry at row "+repr(global_dofN)+". You probably need add diagonal mass or reaction term") - #scaling = 1.0#probably want to add some scaling to match non-dirichlet diagonals in linear system - #for cj in range(self.nc): - # for dofN in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.keys()): - # global_dofN = self.offset[cj]+self.stride[cj]*dofN - # for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]): - # if (self.colind[i] == global_dofN): - # self.nzval[i] = scaling - # else: - # self.nzval[i] = 0.0 - logEvent("Jacobian ",level=10,data=jacobian) - #mwf decide if this is reasonable for solver statistics - self.nonlinear_function_jacobian_evaluations += 1 - return jacobian - def calculateElementQuadrature(self): - """ - Calculate the physical location and weights of the quadrature rules - and the shape information at the quadrature points. - - This function should be called only when the mesh changes. - """ - #self.u[0].femSpace.elementMaps.getValues(self.elementQuadraturePoints, - # self.q['x']) - self.u[0].femSpace.elementMaps.getBasisValuesRef(self.elementQuadraturePoints) - self.u[0].femSpace.elementMaps.getBasisGradientValuesRef(self.elementQuadraturePoints) - self.u[0].femSpace.getBasisValuesRef(self.elementQuadraturePoints) - self.u[0].femSpace.getBasisGradientValuesRef(self.elementQuadraturePoints) - self.coefficients.initializeElementQuadrature(self.timeIntegration.t,self.q) - if self.stabilization != None: - self.stabilization.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) - self.stabilization.initializeTimeIntegration(self.timeIntegration) - if self.shockCapturing != None: - self.shockCapturing.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) - def calculateElementBoundaryQuadrature(self): - pass - def calculateExteriorElementBoundaryQuadrature(self): - """ - Calculate the physical location and weights of the quadrature rules - and the shape information at the quadrature points on global element boundaries. - - This function should be called only when the mesh changes. - """ - # - #get physical locations of element boundary quadrature points - # - #assume all components live on the same mesh - self.u[0].femSpace.elementMaps.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.elementMaps.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.elementMaps.getValuesGlobalExteriorTrace(self.elementBoundaryQuadraturePoints, - self.ebqe['x']) - self.fluxBoundaryConditionsObjectsDict = dict([(cj,FluxBoundaryConditions(self.mesh, - self.nElementBoundaryQuadraturePoints_elementBoundary, - self.ebqe[('x')], - getAdvectiveFluxBoundaryConditions=self.advectiveFluxBoundaryConditionsSetterDict[cj], - getDiffusiveFluxBoundaryConditions=self.diffusiveFluxBoundaryConditionsSetterDictDict[cj])) - for cj in list(self.advectiveFluxBoundaryConditionsSetterDict.keys())]) - self.coefficients.initializeGlobalExteriorElementBoundaryQuadrature(self.timeIntegration.t,self.ebqe) - #argsDict = cArgumentsDict.ArgumentsDict() - #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - #print("Hi", self.coefficients.anb_seepage_flux) - - #print("The seepage is ", anb_seepage_flux) - def estimate_mt(self): - pass - def calculateSolutionAtQuadrature(self): - pass - def calculateAuxiliaryQuantitiesAfterStep(self): - pass - def postStep(self, t, firstStep=False): - with open('seepage_flux_nnnnk', "a") as f: - f.write("\n Time"+ ",\t" +"Seepage\n") - f.write(repr(t)+ ",\t" +repr(self.coefficients.anb_seepage_flux)) - - - -#argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux -#anb_seepage_flux= self.coefficients.anb_seepage_flux -#print("Hi",anb_seepage_flux) - - -#print("Hello from the python file", self.coefficients.anb_seepage_flux) diff --git a/richards_fct/richards/Richards_new.h b/richards_fct/richards/Richards_new.h deleted file mode 100644 index d9e6a76a4a..0000000000 --- a/richards_fct/richards/Richards_new.h +++ /dev/null @@ -1,2966 +0,0 @@ -#ifndef Richards_H -#define Richards_H -#include -#include -#include -#include "CompKernel.h" -#include "ModelFactory.h" -#include "../mprans/ArgumentsDict.h" -#include "xtensor-python/pyarray.hpp" -#define nnz nSpace - -namespace py = pybind11; -#define POWER_SMOOTHNESS_INDICATOR 2 -#define IS_BETAij_ONE 0 -#define GLOBAL_FCT 0 -namespace proteus -{ - // Power entropy // - inline double ENTROPY(const double& phi, const double& phiL, const double& phiR){ - return 1./2.*std::pow(fabs(phi),2.); - } - inline double DENTROPY(const double& phi, const double& phiL, const double& phiR){ - return fabs(phi)*(phi>=0 ? 1 : -1); - } - // Log entropy // for level set from 0 to 1 - inline double ENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ - return std::log(fabs((phi-phiL)*(phiR-phi))+1E-14); - } - inline double DENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ - return (phiL+phiR-2*phi)*((phi-phiL)*(phiR-phi)>=0 ? 1 : -1)/(fabs((phi-phiL)*(phiR-phi))+1E-14); - } -} - -namespace proteus -{ - class Richards_base - { - //The base class defining the interface - public: - virtual ~Richards_base(){} - virtual void calculateResidual(arguments_dict& args)=0; - virtual void calculateJacobian(arguments_dict& args)=0; - virtual void invert(arguments_dict& args)=0; - virtual void FCTStep(arguments_dict& args)=0; - virtual void kth_FCT_step(arguments_dict& args)=0; - virtual void calculateResidual_entropy_viscosity(arguments_dict& args)=0; - virtual void calculateMassMatrix(arguments_dict& args)=0; - }; - - template - class Richards : public Richards_base - { - public: - const int nDOF_test_X_trial_element; - CompKernelType ck; - Richards(): - nDOF_test_X_trial_element(nDOF_test_element*nDOF_trial_element), - ck() - {} - inline - void evaluateCoefficients(const int rowptr[nSpace], - const int colind[nnz], - const double rho, - const double beta, - const double gravity[nSpace], - const double alpha, - const double n_vg, - const double thetaR, - const double thetaSR, - const double KWs[nnz], - const double& u, - double& m, - double& dm, - double f[nSpace], - double df[nSpace], - double a[nnz], - double da[nnz], - double as[nnz], - double& kr, - double& dkr) - { - const int nSpace2 = nSpace * nSpace; - double psiC; - double pcBar; - double pcBar_n; - double pcBar_nM1; - double pcBar_nM2; - double onePlus_pcBar_n; - double sBar; - double sqrt_sBar; - double DsBar_DpsiC; - double thetaW; - double DthetaW_DpsiC; - double vBar; - double vBar2; - double DvBar_DpsiC; - double KWr; - double DKWr_DpsiC; - double rho2 = rho * rho; - double thetaS; - double rhom; - double drhom; - double m_vg; - double pcBarStar; - double sqrt_sBarStar; - - psiC = -u; - m_vg = 1.0 - 1.0 / n_vg; - thetaS = thetaR + thetaSR; - if (psiC > 0.0) - { - pcBar = alpha * psiC; - pcBarStar = pcBar; - if (pcBar < 1.0e-8) - pcBarStar = 1.0e-8; - pcBar_nM2 = pow(pcBarStar, n_vg - 2); - pcBar_nM1 = pcBar_nM2 * pcBar; - pcBar_n = pcBar_nM1 * pcBar; - onePlus_pcBar_n = 1.0 + pcBar_n; - - sBar = pow(onePlus_pcBar_n, -m_vg); - /* using -mn = 1-n */ - DsBar_DpsiC = alpha * (1.0 - n_vg) * (sBar/onePlus_pcBar_n)*pcBar_nM1; - - vBar = 1.0-pcBar_nM1*sBar; - vBar2 = vBar*vBar; - DvBar_DpsiC = -alpha*(n_vg-1.0)*pcBar_nM2*sBar - pcBar_nM1*DsBar_DpsiC; - - thetaW = thetaSR*sBar + thetaR; - DthetaW_DpsiC = thetaSR * DsBar_DpsiC; - - sqrt_sBar = sqrt(sBar); - sqrt_sBarStar = sqrt_sBar; - if (sqrt_sBar < 1.0e-8) - sqrt_sBarStar = 1.0e-8; - KWr= sqrt_sBar*vBar2; - DKWr_DpsiC= ((0.5/sqrt_sBarStar)*DsBar_DpsiC*vBar2 - + - 2.0*sqrt_sBar*vBar*DvBar_DpsiC); - } - else - { - thetaW = thetaS; - DthetaW_DpsiC = 0.0; - KWr = 1.0; - DKWr_DpsiC = 0.0; - } - //slight compressibility - rhom = rho*exp(beta*u); - drhom = beta*rhom; - m = rhom*thetaW; - dm = -rhom*DthetaW_DpsiC+drhom*thetaW; - for (int I=0;I thetaS || thetaW <= thetaR) - { - //cek debug - std::cout<<"rho "< 0.0) - { - isDOFBoundary = 1; - bc_u = bc_u_seepage; - } - else - { - isDOFBoundary = 0; - flux = 0.0; - } - } - /* //set DOF flag and flux correctly if seepage face */ - /* if (isSeepageFace) */ - /* { */ - /* if (flux < 0.0 || u < bc_u_seepage) */ - /* { */ - /* isDOFBoundary = 0; */ - /* flux = 0.0; */ - /* } */ - /* else */ - /* { */ - /* isDOFBoundary = 1; */ - /* bc_u = bc_u_seepage; */ - /* } */ - /* } */ - /* //Dirichlet penalty */ - /* if (isDOFBoundary) */ - /* flux += penalty*(u-bc_u); */ - } - else - flux = bc_flux; - } - - void exteriorNumericalFluxJacobian(const int rowptr[nSpace], - const int colind[nnz], - const int isDOFBoundary, - const double n[nSpace], - const double K[nnz], - const double dK[nnz], - const double grad_psi[nSpace], - const double grad_v[nSpace], - const double dK_rho_g[nSpace], - const double v, - const double penalty, - double& fluxJacobian) - { - if (isDOFBoundary) - { - fluxJacobian = 0.0; - for(int I=0;I& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - double sc_uref = args.scalar("sc_uref"); - double sc_alpha = args.scalar("sc_alpha"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& u_dof_old = args.array("u_dof_old"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m = args.array("q_m"); - xt::pyarray& q_u = args.array("q_u"); - xt::pyarray& q_dV = args.array("q_dV"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - int offset_u = args.scalar("offset_u"); - int stride_u = args.scalar("stride_u"); - xt::pyarray& globalResidual = args.array("globalResidual"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& ebqe_phi = args.array("ebqe_phi"); - double epsFact = args.scalar("epsFact"); - xt::pyarray& ebqe_u = args.array("ebqe_u"); - xt::pyarray& ebqe_flux = args.array("ebqe_flux"); - // PARAMETERS FOR EDGE BASED STABILIZATION - double cE = args.scalar("cE"); - double cK = args.scalar("cK"); - // PARAMETERS FOR LOG BASED ENTROPY FUNCTION - double uL = args.scalar("uL"); - double uR = args.scalar("uR"); - // PARAMETERS FOR EDGE VISCOSITY - int numDOFs = args.scalar("numDOFs"); - int NNZ = args.scalar("NNZ"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); - xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); - xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); - xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); - // C matrices - xt::pyarray& Cx = args.array("Cx"); - xt::pyarray& Cy = args.array("Cy"); - xt::pyarray& Cz = args.array("Cz"); - xt::pyarray& CTx = args.array("CTx"); - xt::pyarray& CTy = args.array("CTy"); - xt::pyarray& CTz = args.array("CTz"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); - int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); - // FOR FCT - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& fluxMatrix = args.array("fluxMatrix"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); - xt::pyarray& min_s_bc = args.array("min_s_bc"); - xt::pyarray& max_s_bc = args.array("max_s_bc"); - // AUX QUANTITIES OF INTEREST - xt::pyarray& quantDOFs = args.array("quantDOFs"); - xt::pyarray& sLow = args.array("sLow"); - xt::pyarray& sn = args.array("sn"); - - assert(a_rowptr.data()[nSpace] == nnz); - assert(a_rowptr.data()[nSpace] == nSpace); - //cek should this be read in? - double Ct_sge = 4.0; - - //loop over elements to compute volume integrals and load them into element and global residual - // - //eN is the element index - //eN_k is the quadrature point index for a scalar - //eN_k_nSpace is the quadrature point index for a vector - //eN_i is the element test function index - //eN_j is the element trial function index - //eN_k_j is the quadrature point index for a trial function - //eN_k_i is the quadrature point index for a trial function - for(int eN=0;eN& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); - xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); - xt::pyarray& globalJacobian = args.array("globalJacobian"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - assert(a_rowptr.data()[nSpace] == nnz); - assert(a_rowptr.data()[nSpace] == nSpace); - double Ct_sge = 4.0; - - // - //loop over elements to compute volume integrals and load them into the element Jacobians and global Jacobian - // - for(int eN=0;eN& bc_mask = args.array("bc_mask"); - int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern - int numDOFs = args.scalar("numDOFs"); //number of DOFs - double dt = args.scalar("dt"); - xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) - xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn - xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn - xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& limited_solution = args.array("limited_solution"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets - xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices - xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 - xt::pyarray& max_s_bc = args.array("max_s_bc"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int MONOLITHIC = args.scalar("MONOLITHIC"); - register double Rpos[numDOFs], Rneg[numDOFs]; - register double FluxCorrectionMatrix[NNZ]; - register double solL[numDOFs]; - register double sdot[numDOFs]; - ////////////////// - // LOOP in DOFs // - ////////////////// - int ij=0; - for (int i=0; i 0) ? 1. : 0.); - Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); - - //update ij - ij+=1; - //std::cout<<"sdoti error"<0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])) - * FluxCorrectionMatrix[ij]; - alpha_dot = fmin(1.0, beta_ij*fabs(alpha_fA)/MassMatrix.data()[ij]/fmax(1.0e-8,fabs(sdoti-sdotj))); - if (MONOLITHIC == 0) - { - ith_Limiter_times_FluxCorrectionMatrix += alpha_fA; - } - else - { - ith_Limiter_times_FluxCorrectionMatrix += alpha_fA + (LUMPED_MASS_MATRIX == 1 ? 0. : 1.)*dt*alpha_dot*MassMatrix.data()[ij]*(sdoti-sdotj); - } - //update ij - ij+=1; - } - limited_solution.data()[i] = solL[i] + 1./lumped_mass_matrix.data()[i]*ith_Limiter_times_FluxCorrectionMatrix*bc_mask[i]; - } - } - - void kth_FCT_step(arguments_dict& args) - { - int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern - int numDOFs = args.scalar("numDOFs"); //number of DOFs - int num_fct_iter = args.scalar("num_fct_iter"); - double dt = args.scalar("dt"); - xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) - xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn - xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn - xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& solLim = args.array("limited_solution"); - xt::pyarray& MC = args.array("MC"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& FluxMatrix = args.array("FluxMatrix"); - xt::pyarray& limitedFlux = args.array("limited_Flux"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets - xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices - xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 - xt::pyarray& max_s_bc = args.array("max_s_bc"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int MONOLITHIC = args.scalar("MONOLITHIC"); - register double Rpos[numDOFs], Rneg[numDOFs]; - int ij=0; - - ////////////////////////////////////////////////////// - // ********** COMPUTE LOW ORDER SOLUTION ********** // - ////////////////////////////////////////////////////// - if (num_fct_iter == 0) - { // No FCT for global bounds - for (int i=0; i 0) ? 1. : 0.); - // update ij - ij+=1; - } - // compute Q vectors - double mi = ML.data()[i]; - double solLimi = solLim.data()[i]; - double Qposi = mi*(maxi-solLimi); - // compute R vectors - Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - } - ij=0; - for (int i=0; i0 ? Rposi : Rpos[j]); - // compute limited flux - ith_Limiter_times_FluxCorrectionMatrix += Lij*Fluxij; - - // update limited flux - limitedFlux.data()[ij] = Lij*Fluxij; - - //update FluxMatrix - FluxMatrix.data()[ij] = Fluxij; - - //update ij - ij+=1; - } - //update limited solution - double mi = ML.data()[i]; - solLim.data()[i] += 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; - } - } - } - - // ***************************************** // - // ********** HIGH ORDER SOLUTION ********** // - // ***************************************** // - ij=0; - for (int i=0; i 0 ? 1. : 0.); - Pnegi += fij * (fij < 0 ? 1. : 0.); - //update ij - ij+=1; - } - // compute Q vectors // - double mi = ML.data()[i]; - double Qposi = mi*(maxi-solLim.data()[i]); - double Qnegi = mi*(mini-solLim.data()[i]); - // compute R vectors // - Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); - } - - // COMPUTE LIMITERS // - ij=0; - for (int i=0; i 0 ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j]); - // compute ith_limited_flux_correction - ith_limited_flux_correction += Lij*fij; - ij+=1; - } - double mi = ML.data()[i]; - solLim[i] += 1./mi*ith_limited_flux_correction; - } - } - - void calculateResidual_entropy_viscosity(arguments_dict& args) - { - xt::pyarray& globalJacobian = args.array("globalJacobian"); - double Theta = args.scalar("Theta"); - xt::pyarray& bc_mask = args.array("bc_mask"); - double dt = args.scalar("dt"); - xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - double sc_uref = args.scalar("sc_uref"); - double sc_alpha = args.scalar("sc_alpha"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& r_l2g = args.array("r_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - int degree_polynomial = args.scalar("degree_polynomial"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& u_dof_old = args.array("u_dof_old"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m = args.array("q_m"); - xt::pyarray& q_u = args.array("q_u"); - xt::pyarray& q_dV = args.array("q_dV"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - int offset_u = args.scalar("offset_u"); - int stride_u = args.scalar("stride_u"); - xt::pyarray& globalResidual = args.array("globalResidual"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& ebqe_phi = args.array("ebqe_phi"); - double epsFact = args.scalar("epsFact"); - xt::pyarray& ebqe_u = args.array("ebqe_u"); - xt::pyarray& ebqe_flux = args.array("ebqe_flux"); - // PARAMETERS FOR EDGE BASED STABILIZATION - double cE = args.scalar("cE"); - double cK = args.scalar("cK"); - // PARAMETERS FOR LOG BASED ENTROPY FUNCTION - double uL = args.scalar("uL"); - double uR = args.scalar("uR"); - // PARAMETERS FOR EDGE VISCOSITY - int numDOFs = args.scalar("numDOFs"); - int NNZ = args.scalar("NNZ"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); - xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); - xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); - xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); - // C matrices - xt::pyarray& Cx = args.array("Cx"); - xt::pyarray& Cy = args.array("Cy"); - xt::pyarray& Cz = args.array("Cz"); - xt::pyarray& CTx = args.array("CTx"); - xt::pyarray& CTy = args.array("CTy"); - xt::pyarray& CTz = args.array("CTz"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); - int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); - // FOR FCT - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& fluxMatrix = args.array("fluxMatrix"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); - xt::pyarray& min_s_bc = args.array("min_s_bc"); - xt::pyarray& max_s_bc = args.array("max_s_bc"); - // AUX QUANTITIES OF INTEREST - xt::pyarray& quantDOFs = args.array("quantDOFs"); - xt::pyarray& sLow = args.array("sLow"); - xt::pyarray& sn = args.array("sn"); - register double Rpos[numDOFs], Rneg[numDOFs]; - //register double FluxCorrectionMatrix[NNZ]; - // NOTE: This function follows a different (but equivalent) implementation of the smoothness based indicator than NCLS.h - // Allocate space for the transport matrices - // This is used for first order KUZMIN'S METHOD - register double TransportMatrix[NNZ],TransportMatrixConsistent[NNZ]; - register double TransportMatrixn[NNZ],TransportMatrixConsistentn[NNZ]; - std::valarray u_free_dof(numDOFs); - std::valarray u_free_dof_old(numDOFs); - std::valarray ML2(numDOFs); - for(int eN=0;eN= 0 && isFluxBoundary_u[ebNE_kb] != 1 ) //outflow. This is handled via the transport matrices. Then flux_ext=0 and dflux_ext!=0 */ - /* { */ - /* dflux_ext = flow; */ - /* flux_ext = 0; */ - /* // save external u */ - /* ebqe_u[ebNE_kb] = u_ext; */ - /* } */ - /* else // inflow. This is handled via the boundary integral. Then flux_ext!=0 and dflux_ext=0 */ - /* { */ - /* dflux_ext = 0; */ - /* // save external u */ - /* ebqe_u[ebNE_kb] = isDOFBoundary_u[ebNE_kb]*ebqe_bc_u_ext[ebNE_kb]+(1-isDOFBoundary_u[ebNE_kb])*u_ext; */ - /* if (isDOFBoundary_u[ebNE_kb] == 1) */ - /* flux_ext = ebqe_bc_u_ext[ebNE_kb]*flow; */ - /* else if (isFluxBoundary_u[ebNE_kb] == 1) */ - /* flux_ext = ebqe_bc_flux_u_ext[ebNE_kb]; */ - /* else */ - /* { */ - /* std::cout<<"warning: VOF open boundary with no external trace, setting to zero for inflow"<= 0.) - { - alpha_numerator_pos += alpha_num; - alpha_denominator_pos += alpha_num; - } - else - { - alpha_numerator_neg += alpha_num; - alpha_denominator_neg += fabs(alpha_num); - } - //update ij - ij+=1; - } - // scale g vector by lumped mass matrix - if (fabs(ML.data()[i] - ML2[i]) > 1.0e-16) - std::cout<<"ML "< 0.0) - // assert( (xi[I] - xj[I]) == delta_x_ij[offset*3+I]); - //gi_times_x += gi[I]*(xi[I]-xj[I]); - gi_times_x += gi[I]*delta_x_ij.data()[offset*3+I]; - } - // compute the positive and negative part of gi*(xi-xj) - SumPos += gi_times_x > 0 ? gi_times_x : 0; - SumNeg += gi_times_x < 0 ? gi_times_x : 0; - } - double sigmaPosi = fmin(1.,(fabs(SumNeg)+1E-15)/(SumPos+1E-15)); - double sigmaNegi = fmin(1.,(SumPos+1E-15)/(fabs(SumNeg)+1E-15)); - double alpha_numi = fabs(sigmaPosi*alpha_numerator_pos + sigmaNegi*alpha_numerator_neg); - double alpha_deni = sigmaPosi*alpha_denominator_pos + sigmaNegi*alpha_denominator_neg; - if (IS_BETAij_ONE == 1) - { - alpha_numi = fabs(alpha_numerator_pos + alpha_numerator_neg); - alpha_deni = alpha_denominator_pos + alpha_denominator_neg; - } - double alphai = alpha_numi/(alpha_deni+1E-15); - quantDOFs.data()[i] = alphai; - - if (POWER_SMOOTHNESS_INDICATOR==0) - psi[i] = 1.0; - else - psi[i] = std::pow(alphai,POWER_SMOOTHNESS_INDICATOR); //NOTE: they use alpha^2 in the paper - } - ///////////////////////////////////////////// - // ** LOOP IN DOFs FOR EDGE BASED TERMS ** // - ///////////////////////////////////////////// - ij=0; - for (int i=0; i Dissipation matrices as well. - double soli = u_free_dof[i]; // solution at time tn for the ith DOF - double solni = u_free_dof_old[i]; // solution at time tn for the ith DOF - for (int I=0;I mMax) - { - std::cout<<"mass out of bounds "< 0) ? 1. : 0.); - // Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); - // ij+=1; - // } - // double mi = ML[i]; - // double solni = u_dof_old[i]; - // double Qposi = mi*(maxi-solni); - // double Qnegi = mi*(mini-solni); - - //std::cout << Qposi << std::endl; - // Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - // Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); - - //if (Rpos[i] < 0) - //{ - // std::cout << mi << "\t" << maxi << "\t" << solni << std::endl; - // std::cout << Qposi << "\t" << Pposi << std::endl; - // std::cout << Rpos[i] << std::endl; - //abort(); - //} - //} - - //ij=0; - //for (int i=0; i 1.0 || Rposi < 0.0) - //std::cout << "Rposi: " << Rposi << std::endl; - //if (Rnegi > 1.0 || Rnegi < 0.0) - //std::cout << "Rnegi: " << Rnegi << std::endl; - - // LOOP OVER THE SPARSITY PATTERN (j-LOOP)// - // for (int offset=csrRowIndeces_DofLoops.data()[i]; - // offset0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])); - // //Lij=0.0; - // ith_Limiter_times_FluxCorrectionMatrix += Lij*FluxCorrectionMatrix[ij]; - // //update ij - // ij+=1; - // } - // double mi = ML[i]; - // double solni = u_dof_old[i]; - // globalResidual[i] = solni + 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; - //} - - } - - void invert(arguments_dict& args) - { - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - xt::pyarray& globalResidual = args.array("globalResidual"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - int numDOFs = args.scalar("numDOFs"); - for (int i=0; i mMax) - { - std::cout<<"mass out of bounds "<("dt"); - xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - //element boundary - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - //physics - int nElements_global = args.scalar("nElements_global"); - //new - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - //end new - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& r_l2g = args.array("r_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - int degree_polynomial = args.scalar("degree_polynomial"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); - xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); - xt::pyarray& globalJacobian = args.array("globalJacobian"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - //std::cout<<"ndjaco address "<(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - else if (nSpaceIn == 2) - return proteus::chooseAndAllocateDiscretization2D(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - else - { - assert(nSpaceIn == 3); - return proteus::chooseAndAllocateDiscretization(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - } - } -}//proteus -#endif diff --git a/richards_fct/richards/Richards_new.py b/richards_fct/richards/Richards_new.py deleted file mode 100644 index 841fcd0884..0000000000 --- a/richards_fct/richards/Richards_new.py +++ /dev/null @@ -1,1745 +0,0 @@ -from __future__ import division -from builtins import range -from past.utils import old_div -import proteus -from .cRichards import * -import numpy as np -from proteus.Transport import OneLevelTransport -from proteus.Transport import TC_base, NonlinearEquation, logEvent, memory -from proteus.Transport import FluxBoundaryConditions, Comm, cfemIntegrals -from proteus.Transport import DOFBoundaryConditions, Quadrature -from proteus.mprans import cArgumentsDict -from proteus.LinearAlgebraTools import SparseMat -from proteus import TimeIntegration -from proteus.NonlinearSolvers import ExplicitLumpedMassMatrixForRichards - -class ThetaScheme(TimeIntegration.BackwardEuler): - def __init__(self,transport,integrateInterpolationPoints=False): - self.transport=transport - TimeIntegration.BackwardEuler.__init__(self,transport, integrateInterpolationPoints) - def updateTimeHistory(self,resetFromDOF=False): - TimeIntegration.BackwardEuler.updateTimeHistory(self,resetFromDOF) - self.transport.u_dof_old[:] = self.u -class RKEV(TimeIntegration.SSP): - from proteus import TimeIntegration - """ - Wrapper for SSPRK time integration using EV - - ... more to come ... - """ - - def __init__(self, transport, timeOrder=1, runCFL=0.1, integrateInterpolationPoints=False): - TimeIntegration.SSP.__init__(self, transport, integrateInterpolationPoints=integrateInterpolationPoints) - self.runCFL = runCFL - self.dtLast = None - self.isAdaptive = True - # About the cfl - assert transport.coefficients.STABILIZATION_TYPE > 0, "SSP method just works for edge based EV methods; i.e., STABILIZATION_TYPE>0" - assert hasattr(transport, 'edge_based_cfl'), "No edge based cfl defined" - self.cfl = transport.edge_based_cfl - # Stuff particular for SSP - self.timeOrder = timeOrder # order of approximation - self.nStages = timeOrder # number of stages total - self.lstage = 0 # last stage completed - # storage vectors - self.u_dof_last = {} - # per component stage values, list with array at each stage - self.u_dof_stage = {} - for ci in range(self.nc): - if ('m', ci) in transport.q: - self.u_dof_last[ci] = transport.u[ci].dof.copy() - self.u_dof_stage[ci] = [] - for k in range(self.nStages + 1): - self.u_dof_stage[ci].append(transport.u[ci].dof.copy()) - - # def set_dt(self, DTSET): - # self.dt = DTSET # don't update t - def choose_dt(self): - comm = Comm.get() - maxCFL = 1.0e-6 - maxCFL = max(maxCFL, comm.globalMax(self.cfl.max())) - self.dt = old_div(self.runCFL, maxCFL) - if self.dtLast is None: - self.dtLast = self.dt - self.t = self.tLast + self.dt - self.substeps = [self.t for i in range(self.nStages)] # Manuel is ignoring different time step levels for now - - def initialize_dt(self, t0, tOut, q): - """ - Modify self.dt - """ - self.tLast = t0 - self.choose_dt() - self.t = t0 + self.dt - - def setCoefficients(self): - """ - beta are all 1's here - mwf not used right now - """ - self.alpha = np.zeros((self.nStages, self.nStages), 'd') - self.dcoefs = np.zeros((self.nStages), 'd') - - def updateStage(self): - """ - Need to switch to use coefficients - """ - self.lstage += 1 - assert self.timeOrder in [1, 2, 3] - assert self.lstage > 0 and self.lstage <= self.timeOrder - if self.timeOrder == 3: - if self.lstage == 1: - logEvent("First stage of SSP33 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - # update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] - elif self.lstage == 2: - logEvent("Second stage of SSP33 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - self.u_dof_stage[ci][self.lstage] *= old_div(1., 4.) - self.u_dof_stage[ci][self.lstage] += 3. / 4. * self.u_dof_last[ci] - # Update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] - elif self.lstage == 3: - logEvent("Third stage of SSP33 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - self.u_dof_stage[ci][self.lstage] *= old_div(2.0, 3.0) - self.u_dof_stage[ci][self.lstage] += 1.0 / 3.0 * self.u_dof_last[ci] - # update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_last[ci] - # update solution to u[0].dof - self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] - elif self.timeOrder == 2: - if self.lstage == 1: - logEvent("First stage of SSP22 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - # Update u_dof_old - self.transport.u_dof_old[:] = self.transport.u[ci].dof - elif self.lstage == 2: - logEvent("Second stage of SSP22 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - self.u_dof_stage[ci][self.lstage][:] *= old_div(1., 2.) - self.u_dof_stage[ci][self.lstage][:] += 1. / 2. * self.u_dof_last[ci] - # update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_last[ci] - # update solution to u[0].dof - self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] - else: - assert self.timeOrder == 1 - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof[:] - self.transport.u_dof_old[:] = self.transport.u[ci].dof - - def initializeTimeHistory(self, resetFromDOF=True): - """ - Push necessary information into time history arrays - """ - for ci in range(self.nc): - self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] - for k in range(self.nStages): - self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] - - def updateTimeHistory(self, resetFromDOF=False): - """ - assumes successful step has been taken - """ - - self.t = self.tLast + self.dt - for ci in range(self.nc): - self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] - for k in range(self.nStages): - self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] - self.lstage = 0 - self.dtLast = self.dt - self.tLast = self.t - - def generateSubsteps(self, tList): - """ - create list of substeps over time values given in tList. These correspond to stages - """ - self.substeps = [] - tLast = self.tLast - for t in tList: - dttmp = t - tLast - self.substeps.extend([tLast + dttmp for i in range(self.nStages)]) - tLast = t - - def resetOrder(self, order): - """ - initialize data structures for stage updges - """ - self.timeOrder = order # order of approximation - self.nStages = order # number of stages total - self.lstage = 0 # last stage completed - # storage vectors - # per component stage values, list with array at each stage - self.u_dof_stage = {} - for ci in range(self.nc): - if ('m', ci) in self.transport.q: - self.u_dof_stage[ci] = [] - for k in range(self.nStages + 1): - self.u_dof_stage[ci].append(self.transport.u[ci].dof.copy()) - self.substeps = [self.t for i in range(self.nStages)] - - def setFromOptions(self, nOptions): - """ - allow classes to set various numerical parameters - """ - if 'runCFL' in dir(nOptions): - self.runCFL = nOptions.runCFL - flags = ['timeOrder'] - for flag in flags: - if flag in dir(nOptions): - val = getattr(nOptions, flag) - setattr(self, flag, val) - if flag == 'timeOrder': - self.resetOrder(self.timeOrder) - -class Coefficients(proteus.TransportCoefficients.TC_base): - """ - version of Re where element material type id's used in evals - """ - from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2 - from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchten_sd_het - def __init__(self, - nd, - Ksw_types, - vgm_n_types, - vgm_alpha_types, - thetaR_types, - thetaSR_types, - gravity, - density, - beta, - diagonal_conductivity=True, - getSeepageFace=None, - # FOR EDGE BASED EV - STABILIZATION_TYPE=0, - ENTROPY_TYPE=2, # logarithmic - LUMPED_MASS_MATRIX=False, - MONOLITHIC=True, - FCT=False, - forceStrongBoundaryConditions=False, - num_fct_iter=1, - # FOR ENTROPY VISCOSITY - cE=1.0, - uL=0.0, - uR=1.0, - # FOR ARTIFICIAL COMPRESSION - cK=1.0, - # OUTPUT quantDOFs - outputQuantDOFs=False): - variableNames=['pressure_head'] - nc=1 - mass={0:{0:'nonlinear'}} - advection={0:{0:'nonlinear'}} - diffusion={0:{0:{0:'nonlinear'}}} - potential={0:{0:'u'}} - reaction={0:{0:'linear'}} - hamiltonian={} - self.getSeepageFace=getSeepageFace - self.gravity=gravity - self.rho = density - self.beta=beta - self.vgm_n_types = vgm_n_types - self.vgm_alpha_types = vgm_alpha_types - self.thetaR_types = thetaR_types - self.thetaSR_types = thetaSR_types - self.elementMaterialTypes = None - self.exteriorElementBoundaryTypes = None - self.materialTypes_q = None - self.materialTypes_ebq = None - self.materialTypes_ebqe = None - self.nd = nd - self.nMaterialTypes = len(thetaR_types) - self.q = {}; self.ebqe = {}; self.ebq = {}; self.ebq_global={} - #try to allow some flexibility in input of permeability/conductivity tensor - self.diagonal_conductivity = diagonal_conductivity - self.Ksw_types_in = Ksw_types - if self.diagonal_conductivity: - sparseDiffusionTensors = {(0,0):(np.arange(self.nd+1,dtype='i'), - np.arange(self.nd,dtype='i'))} - - assert len(Ksw_types.shape) in [1,2], "if diagonal conductivity true then Ksw_types scalar or vector of diagonal entries" - #allow scalar input Ks - if len(Ksw_types.shape)==1: - self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd),'d') - for I in range(self.nd): - self.Ksw_types[:,I] = Ksw_types - else: - self.Ksw_types = Ksw_types - else: #full - sparseDiffusionTensors = {(0,0):(np.arange(self.nd**2+1,step=self.nd,dtype='i'), - np.array([list(range(self.nd)) for row in range(self.nd)],dtype='i'))} - assert len(Ksw_types.shape) in [1,2], "if full tensor conductivity true then Ksw_types scalar or 'flattened' row-major representation of entries" - if len(Ksw_types.shape)==1: - self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd**2),'d') - for I in range(self.nd): - self.Ksw_types[:,I*self.nd+I] = Ksw_types - else: - assert Ksw_types.shape[1] == self.nd**2 - self.Ksw_types = Ksw_types - # EDGE BASED (AND ENTROPY) VISCOSITY - self.LUMPED_MASS_MATRIX = LUMPED_MASS_MATRIX - self.MONOLITHIC = MONOLITHIC - self.STABILIZATION_TYPE = STABILIZATION_TYPE - self.ENTROPY_TYPE = ENTROPY_TYPE - self.FCT = FCT - self.num_fct_iter=num_fct_iter - self.uL = uL - self.uR = uR - self.cK = cK - self.forceStrongConditions = forceStrongBoundaryConditions - self.cE = cE - self.outputQuantDOFs = outputQuantDOFs - TC_base.__init__(self, - nc, - mass, - advection, - diffusion, - potential, - reaction, - hamiltonian, - variableNames, - sparseDiffusionTensors = sparseDiffusionTensors, - useSparseDiffusion = True) - - def initializeMesh(self,mesh): - from proteus.SubsurfaceTransportCoefficients import BlockHeterogeneousCoefficients - self.elementMaterialTypes,self.exteriorElementBoundaryTypes,self.elementBoundaryTypes = BlockHeterogeneousCoefficients(mesh).initializeMaterialTypes() - #want element boundary material types for evaluating heterogeneity - #not boundary conditions - self.isSeepageFace = np.zeros((mesh.nExteriorElementBoundaries_global),'i') - if self.getSeepageFace != None: - for ebNE in range(mesh.nExteriorElementBoundaries_global): - #mwf missing ebNE-->ebN? - ebN = mesh.exteriorElementBoundariesArray[ebNE] - #print "eb flag",mesh.elementBoundaryMaterialTypes[ebN] - #print self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) - self.isSeepageFace[ebNE] = self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) - #print self.isSeepageFace - def initializeElementQuadrature(self,t,cq): - self.materialTypes_q = self.elementMaterialTypes - self.q_shape = cq[('u',0)].shape -# cq['Ks'] = np.zeros(self.q_shape,'d') -# for k in range(self.q_shape[1]): -# cq['Ks'][:,k] = self.Ksw_types[self.elementMaterialTypes,0] - self.q[('vol_frac',0)] = np.zeros(self.q_shape,'d') - def initializeElementBoundaryQuadrature(self,t,cebq,cebq_global): - self.materialTypes_ebq = np.zeros(cebq[('u',0)].shape[0:2],'i') - self.ebq_shape = cebq[('u',0)].shape - for ebN_local in range(self.ebq_shape[1]): - self.materialTypes_ebq[:,ebN_local] = self.elementMaterialTypes - self.ebq[('vol_frac',0)] = np.zeros(self.ebq_shape,'d') - - def initializeGlobalExteriorElementBoundaryQuadrature(self,t,cebqe): - self.materialTypes_ebqe = self.exteriorElementBoundaryTypes - self.ebqe_shape = cebqe[('u',0)].shape - self.ebqe[('vol_frac',0)] = np.zeros(self.ebqe_shape,'d') - # - def evaluate(self,t,c): - if c[('u',0)].shape == self.q_shape: - materialTypes = self.materialTypes_q - vol_frac = self.q[('vol_frac',0)] - elif c[('u',0)].shape == self.ebqe_shape: - materialTypes = self.materialTypes_ebqe - vol_frac = self.ebqe[('vol_frac',0)] - elif c[('u',0)].shape == self.ebq_shape: - materialTypes = self.materialTypes_ebq - vol_frac = self.ebq[('vol_frac',0)] - else: - assert False, "no materialType found to match c[('u',0)].shape= %s " % c[('u',0)].shape - self.conservativeHeadRichardsMualemVanGenuchten_sd_het(self.sdInfo[(0,0)][0], - self.sdInfo[(0,0)][1], - materialTypes, - self.rho, - self.beta, - self.gravity, - self.vgm_alpha_types, - self.vgm_n_types, - self.thetaR_types, - self.thetaSR_types, - self.Ksw_types, - c[('u',0)], - c[('m',0)], - c[('dm',0,0)], - c[('f',0)], - c[('df',0,0)], - c[('a',0,0)], - c[('da',0,0,0)], - vol_frac) - # print "Picard---------------------------------------------------------------" - # c[('df',0,0)][:] = 0.0 - # c[('da',0,0,0)][:] = 0.0 -# self.conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2(materialTypes, -# self.rho, -# self.beta, -# self.gravity, -# self.vgm_alpha_types, -# self.vgm_n_types, -# self.thetaR_types, -# self.thetaSR_types, -# self.Ksw_types, -# c[('u',0)], -# c[('m',0)], -# c[('dm',0,0)], -# c[('f',0)], -# c[('df',0,0)], -# c[('a',0,0)], -# c[('da',0,0,0)]) - #mwf debug - if (np.isnan(c[('da',0,0,0)]).any() or - np.isnan(c[('a',0,0)]).any() or - np.isnan(c[('df',0,0)]).any() or - np.isnan(c[('f',0)]).any() or - np.isnan(c[('u',0)]).any() or - np.isnan(c[('m',0)]).any() or - np.isnan(c[('dm',0,0)]).any()): - import pdb - pdb.set_trace() - -# #mwf debug -# if c[('u',0)].shape == self.q_shape: -# c[('visPerm',0)]=c[('a',0,0)][:,:,0,0] - -class LevelModel(proteus.Transport.OneLevelTransport): - nCalls=0 - def __init__(self, - uDict, - phiDict, - testSpaceDict, - matType, - dofBoundaryConditionsDict, - dofBoundaryConditionsSetterDict, - coefficients, - elementQuadrature, - elementBoundaryQuadrature, - fluxBoundaryConditionsDict=None, - advectiveFluxBoundaryConditionsSetterDict=None, - diffusiveFluxBoundaryConditionsSetterDictDict=None, - stressTraceBoundaryConditionsSetterDict=None, - stabilization=None, - shockCapturing=None, - conservativeFluxDict=None, - numericalFluxType=None, - TimeIntegrationClass=None, - massLumping=False, - reactionLumping=False, - options=None, - name='defaultName', - reuse_trial_and_test_quadrature=True, - sd = True, - movingDomain=False, - bdyNullSpace=False): - self.bdyNullSpace=bdyNullSpace - # - #set the objects describing the method and boundary conditions - # - self.movingDomain=movingDomain - self.tLast_mesh=None - # - self.name=name - self.sd=sd - self.Hess=False - self.lowmem=True - self.timeTerm=True#allow turning off the time derivative - #self.lowmem=False - self.testIsTrial=True - self.phiTrialIsTrial=True - self.u = uDict - self.ua = {}#analytical solutions - self.phi = phiDict - self.dphi={} - self.matType = matType - #mwf try to reuse test and trial information across components if spaces are the same - self.reuse_test_trial_quadrature = reuse_trial_and_test_quadrature#True#False - if self.reuse_test_trial_quadrature: - for ci in range(1,coefficients.nc): - assert self.u[ci].femSpace.__class__.__name__ == self.u[0].femSpace.__class__.__name__, "to reuse_test_trial_quad all femSpaces must be the same!" - self.u_dof_old = None - ## Simplicial Mesh - self.mesh = self.u[0].femSpace.mesh #assume the same mesh for all components for now - self.testSpace = testSpaceDict - self.dirichletConditions = dofBoundaryConditionsDict - self.dirichletNodeSetList=None #explicit Dirichlet conditions for now, no Dirichlet BC constraints - self.coefficients = coefficients - self.coefficients.initializeMesh(self.mesh) - self.nc = self.coefficients.nc - self.stabilization = stabilization - self.shockCapturing = shockCapturing - self.conservativeFlux = conservativeFluxDict #no velocity post-processing for now - self.fluxBoundaryConditions=fluxBoundaryConditionsDict - self.advectiveFluxBoundaryConditionsSetterDict=advectiveFluxBoundaryConditionsSetterDict - self.diffusiveFluxBoundaryConditionsSetterDictDict = diffusiveFluxBoundaryConditionsSetterDictDict - #determine whether the stabilization term is nonlinear - self.stabilizationIsNonlinear = False - #cek come back - if self.stabilization != None: - for ci in range(self.nc): - if ci in coefficients.mass: - for flag in list(coefficients.mass[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.advection: - for flag in list(coefficients.advection[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.diffusion: - for diffusionDict in list(coefficients.diffusion[ci].values()): - for flag in list(diffusionDict.values()): - if flag != 'constant': - self.stabilizationIsNonlinear=True - if ci in coefficients.potential: - for flag in list(coefficients.potential[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.reaction: - for flag in list(coefficients.reaction[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.hamiltonian: - for flag in list(coefficients.hamiltonian[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - #determine if we need element boundary storage - self.elementBoundaryIntegrals = {} - for ci in range(self.nc): - self.elementBoundaryIntegrals[ci] = ((self.conservativeFlux != None) or - (numericalFluxType != None) or - (self.fluxBoundaryConditions[ci] == 'outFlow') or - (self.fluxBoundaryConditions[ci] == 'mixedFlow') or - (self.fluxBoundaryConditions[ci] == 'setFlow')) - # - #calculate some dimensions - # - self.nSpace_global = self.u[0].femSpace.nSpace_global #assume same space dim for all variables - self.nDOF_trial_element = [u_j.femSpace.max_nDOF_element for u_j in list(self.u.values())] - self.nDOF_phi_trial_element = [phi_k.femSpace.max_nDOF_element for phi_k in list(self.phi.values())] - self.n_phi_ip_element = [phi_k.femSpace.referenceFiniteElement.interpolationConditions.nQuadraturePoints for phi_k in list(self.phi.values())] - self.nDOF_test_element = [femSpace.max_nDOF_element for femSpace in list(self.testSpace.values())] - self.nFreeDOF_global = [dc.nFreeDOF_global for dc in list(self.dirichletConditions.values())] - self.nVDOF_element = sum(self.nDOF_trial_element) - self.nFreeVDOF_global = sum(self.nFreeDOF_global) - # - NonlinearEquation.__init__(self,self.nFreeVDOF_global) - # - #build the quadrature point dictionaries from the input (this - #is just for convenience so that the input doesn't have to be - #complete) - # - elementQuadratureDict={} - elemQuadIsDict = isinstance(elementQuadrature,dict) - if elemQuadIsDict: #set terms manually - for I in self.coefficients.elementIntegralKeys: - if I in elementQuadrature: - elementQuadratureDict[I] = elementQuadrature[I] - else: - elementQuadratureDict[I] = elementQuadrature['default'] - else: - for I in self.coefficients.elementIntegralKeys: - elementQuadratureDict[I] = elementQuadrature - if self.stabilization != None: - for I in self.coefficients.elementIntegralKeys: - if elemQuadIsDict: - if I in elementQuadrature: - elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature[I] - else: - elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature['default'] - else: - elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature - if self.shockCapturing != None: - for ci in self.shockCapturing.components: - if elemQuadIsDict: - if ('numDiff',ci,ci) in elementQuadrature: - elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature[('numDiff',ci,ci)] - else: - elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature['default'] - else: - elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature - if massLumping: - for ci in list(self.coefficients.mass.keys()): - elementQuadratureDict[('m',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - for I in self.coefficients.elementIntegralKeys: - elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - if reactionLumping: - for ci in list(self.coefficients.mass.keys()): - elementQuadratureDict[('r',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - for I in self.coefficients.elementIntegralKeys: - elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - elementBoundaryQuadratureDict={} - if isinstance(elementBoundaryQuadrature,dict): #set terms manually - for I in self.coefficients.elementBoundaryIntegralKeys: - if I in elementBoundaryQuadrature: - elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature[I] - else: - elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature['default'] - else: - for I in self.coefficients.elementBoundaryIntegralKeys: - elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature - # - # find the union of all element quadrature points and - # build a quadrature rule for each integral that has a - # weight at each point in the union - #mwf include tag telling me which indices are which quadrature rule? - (self.elementQuadraturePoints,self.elementQuadratureWeights, - self.elementQuadratureRuleIndeces) = Quadrature.buildUnion(elementQuadratureDict) - self.nQuadraturePoints_element = self.elementQuadraturePoints.shape[0] - self.nQuadraturePoints_global = self.nQuadraturePoints_element*self.mesh.nElements_global - # - #Repeat the same thing for the element boundary quadrature - # - (self.elementBoundaryQuadraturePoints, - self.elementBoundaryQuadratureWeights, - self.elementBoundaryQuadratureRuleIndeces) = Quadrature.buildUnion(elementBoundaryQuadratureDict) - self.nElementBoundaryQuadraturePoints_elementBoundary = self.elementBoundaryQuadraturePoints.shape[0] - self.nElementBoundaryQuadraturePoints_global = (self.mesh.nElements_global* - self.mesh.nElementBoundaries_element* - self.nElementBoundaryQuadraturePoints_elementBoundary) -# if isinstance(self.u[0].femSpace,C0_AffineLinearOnSimplexWithNodalBasis): -# print self.nQuadraturePoints_element -# if self.nSpace_global == 3: -# assert(self.nQuadraturePoints_element == 5) -# elif self.nSpace_global == 2: -# assert(self.nQuadraturePoints_element == 6) -# elif self.nSpace_global == 1: -# assert(self.nQuadraturePoints_element == 3) -# -# print self.nElementBoundaryQuadraturePoints_elementBoundary -# if self.nSpace_global == 3: -# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) -# elif self.nSpace_global == 2: -# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) -# elif self.nSpace_global == 1: -# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 1) - - # - #storage dictionaries - self.scalars_element = set() - # - #simplified allocations for test==trial and also check if space is mixed or not - # - self.q={} - self.ebq={} - self.ebq_global={} - self.ebqe={} - self.phi_ip={} - self.edge_based_cfl = np.zeros(self.u[0].dof.shape)+100 - #mesh - #self.q['x'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,3),'d') - self.q[('dV_u', 0)] = (old_div(1.0, self.mesh.nElements_global)) * np.ones((self.mesh.nElements_global, self.nQuadraturePoints_element), 'd') - self.ebqe['x'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,3),'d') - self.q[('u',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') - self.q[('grad(u)',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') - self.q['velocity'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') - self.q[('m',0)] = self.q[('u',0)].copy() - self.q[('mt',0)] = self.q[('u',0)].copy() - self.q[('m_last',0)] = self.q[('u',0)].copy() - self.q[('m_tmp',0)] = self.q[('u',0)].copy() - self.q[('cfl',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') - self.q[('numDiff',0,0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') - self.ebqe[('u',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.ebqe[('grad(u)',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') - self.ebqe['velocity'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') - self.ebqe[('advectiveFlux_bc_flag',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'i') - self.ebqe[('advectiveFlux_bc',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.ebqe[('advectiveFlux',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.ebqe[('penalty')] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.points_elementBoundaryQuadrature= set() - self.scalars_elementBoundaryQuadrature= set([('u',ci) for ci in range(self.nc)]) - self.vectors_elementBoundaryQuadrature= set() - self.tensors_elementBoundaryQuadrature= set() - self.inflowBoundaryBC = {} - self.inflowBoundaryBC_values = {} - self.inflowFlux = {} - for cj in range(self.nc): - self.inflowBoundaryBC[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,),'i') - self.inflowBoundaryBC_values[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nDOF_trial_element[cj]),'d') - self.inflowFlux[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.internalNodes = set(range(self.mesh.nNodes_global)) - #identify the internal nodes this is ought to be in mesh - ##\todo move this to mesh - for ebNE in range(self.mesh.nExteriorElementBoundaries_global): - ebN = self.mesh.exteriorElementBoundariesArray[ebNE] - eN_global = self.mesh.elementBoundaryElementsArray[ebN,0] - ebN_element = self.mesh.elementBoundaryLocalElementBoundariesArray[ebN,0] - for i in range(self.mesh.nNodes_element): - if i != ebN_element: - I = self.mesh.elementNodesArray[eN_global,i] - self.internalNodes -= set([I]) - self.nNodes_internal = len(self.internalNodes) - self.internalNodesArray=np.zeros((self.nNodes_internal,),'i') - for nI,n in enumerate(self.internalNodes): - self.internalNodesArray[nI]=n - # - del self.internalNodes - self.internalNodes = None - logEvent("Updating local to global mappings",2) - self.updateLocal2Global() - logEvent("Building time integration object",2) - logEvent(memory("inflowBC, internalNodes,updateLocal2Global","OneLevelTransport"),level=4) - #mwf for interpolating subgrid error for gradients etc - if self.stabilization and self.stabilization.usesGradientStabilization: - self.timeIntegration = TimeIntegrationClass(self,integrateInterpolationPoints=True) - else: - self.timeIntegration = TimeIntegrationClass(self) - - if options != None: - self.timeIntegration.setFromOptions(options) - logEvent(memory("TimeIntegration","OneLevelTransport"),level=4) - logEvent("Calculating numerical quadrature formulas",2) - self.calculateQuadrature() - #lay out components/equations contiguously for now - self.offset = [0] - for ci in range(1,self.nc): - self.offset += [self.offset[ci-1]+self.nFreeDOF_global[ci-1]] - self.stride = [1 for ci in range(self.nc)] - #use contiguous layout of components for parallel, requires weak DBC's - # mql. Some ASSERTS to restrict the combination of the methods - if self.coefficients.STABILIZATION_TYPE > 0: - pass - #assert self.timeIntegration.isSSP == True, "If STABILIZATION_TYPE>0, use RKEV timeIntegration within VOF model" - #cond = 'levelNonlinearSolver' in dir(options) and (options.levelNonlinearSolver == - # ExplicitLumpedMassMatrixForRichards or options.levelNonlinearSolver == ExplicitConsistentMassMatrixForRichards) - #assert cond, "If STABILIZATION_TYPE>0, use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards or ExplicitConsistentMassMatrixForRichards" - try: - if 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards: - assert self.coefficients.LUMPED_MASS_MATRIX, "If levelNonlinearSolver=ExplicitLumpedMassMatrix, use LUMPED_MASS_MATRIX=True" - except: - pass - if self.coefficients.LUMPED_MASS_MATRIX == True: - cond = self.coefficients.STABILIZATION_TYPE == 2 - assert cond, "Use lumped mass matrix just with: STABILIZATION_TYPE=2 (smoothness based stab.)" - cond = 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards - assert cond, "Use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards when the mass matrix is lumped" - if self.coefficients.FCT == True: - cond = self.coefficients.STABILIZATION_TYPE > 0, "Use FCT just with STABILIZATION_TYPE>0; i.e., edge based stabilization" - # END OF ASSERTS - - # cek adding empty data member for low order numerical viscosity structures here for now - self.ML = None # lumped mass matrix - self.MC_global = None # consistent mass matrix - self.cterm_global = None - self.cterm_transpose_global = None - # dL_global and dC_global are not the full matrices but just the CSR arrays containing the non zero entries - self.residualComputed=False #TMP - self.dLow= None - self.fluxMatrix = None - self.uDotLow = None - self.uLow = None - self.dt_times_dC_minus_dL = None - self.min_s_bc = None - self.max_s_bc = None - # Aux quantity at DOFs to be filled by optimized code (MQL) - self.quantDOFs = np.zeros(self.u[0].dof.shape, 'd') - self.sLow = np.zeros(self.u[0].dof.shape, 'd') - self.sHigh = np.zeros(self.u[0].dof.shape, 'd') - self.sn = np.zeros(self.u[0].dof.shape, 'd') - comm = Comm.get() - self.comm=comm - if comm.size() > 1: - assert numericalFluxType != None and numericalFluxType.useWeakDirichletConditions,"You must use a numerical flux to apply weak boundary conditions for parallel runs" - self.offset = [0] - for ci in range(1,self.nc): - self.offset += [ci] - self.stride = [self.nc for ci in range(self.nc)] - # - logEvent(memory("stride+offset","OneLevelTransport"),level=4) - if numericalFluxType != None: - if options is None or options.periodicDirichletConditions is None: - self.numericalFlux = numericalFluxType(self, - dofBoundaryConditionsSetterDict, - advectiveFluxBoundaryConditionsSetterDict, - diffusiveFluxBoundaryConditionsSetterDictDict) - else: - self.numericalFlux = numericalFluxType(self, - dofBoundaryConditionsSetterDict, - advectiveFluxBoundaryConditionsSetterDict, - diffusiveFluxBoundaryConditionsSetterDictDict, - options.periodicDirichletConditions) - else: - self.numericalFlux = None - #set penalty terms - #cek todo move into numerical flux initialization - if 'penalty' in self.ebq_global: - for ebN in range(self.mesh.nElementBoundaries_global): - for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): - self.ebq_global['penalty'][ebN,k] = old_div(self.numericalFlux.penalty_constant,(self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power)) - #penalty term - #cek move to Numerical flux initialization - if 'penalty' in self.ebqe: - for ebNE in range(self.mesh.nExteriorElementBoundaries_global): - ebN = self.mesh.exteriorElementBoundariesArray[ebNE] - for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): - self.ebqe['penalty'][ebNE,k] = old_div(self.numericalFlux.penalty_constant,self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power) - logEvent(memory("numericalFlux","OneLevelTransport"),level=4) - self.elementEffectiveDiametersArray = self.mesh.elementInnerDiametersArray - #use post processing tools to get conservative fluxes, None by default - from proteus import PostProcessingTools - self.velocityPostProcessor = PostProcessingTools.VelocityPostProcessingChooser(self) - logEvent(memory("velocity postprocessor","OneLevelTransport"),level=4) - #helper for writing out data storage - from proteus import Archiver - self.elementQuadratureDictionaryWriter = Archiver.XdmfWriter() - self.elementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() - self.exteriorElementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() - #TODO get rid of this - for ci,fbcObject in list(self.fluxBoundaryConditionsObjectsDict.items()): - self.ebqe[('advectiveFlux_bc_flag',ci)] = np.zeros(self.ebqe[('advectiveFlux_bc',ci)].shape,'i') - for t,g in list(fbcObject.advectiveFluxBoundaryConditionsDict.items()): - if ci in self.coefficients.advection: - self.ebqe[('advectiveFlux_bc',ci)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) - self.ebqe[('advectiveFlux_bc_flag',ci)][t[0],t[1]] = 1 - - if hasattr(self.numericalFlux,'setDirichletValues'): - self.numericalFlux.setDirichletValues(self.ebqe) - if not hasattr(self.numericalFlux,'isDOFBoundary'): - self.numericalFlux.isDOFBoundary = {0:np.zeros(self.ebqe[('u',0)].shape,'i')} - if not hasattr(self.numericalFlux,'ebqe'): - self.numericalFlux.ebqe = {('u',0):np.zeros(self.ebqe[('u',0)].shape,'d')} - #TODO how to handle redistancing calls for calculateCoefficients,calculateElementResidual etc - self.globalResidualDummy = None - compKernelFlag=0 - self.delta_x_ij=None - self.richards = cRichards_base(self.nSpace_global, - self.nQuadraturePoints_element, - self.u[0].femSpace.elementMaps.localFunctionSpace.dim, - self.u[0].femSpace.referenceFiniteElement.localFunctionSpace.dim, - self.testSpace[0].referenceFiniteElement.localFunctionSpace.dim, - self.nElementBoundaryQuadraturePoints_elementBoundary, - compKernelFlag) - if self.movingDomain: - self.MOVING_DOMAIN=1.0 - else: - self.MOVING_DOMAIN=0.0 - #cek hack - self.movingDomain=False - self.MOVING_DOMAIN=0.0 - if self.mesh.nodeVelocityArray is None: - self.mesh.nodeVelocityArray = np.zeros(self.mesh.nodeArray.shape,'d') - self.forceStrongConditions=self.coefficients.forceStrongConditions - self.dirichletConditionsForceDOF = {} - if self.forceStrongConditions: - for cj in range(self.nc): - self.dirichletConditionsForceDOF[cj] = DOFBoundaryConditions(self.u[cj].femSpace,dofBoundaryConditionsSetterDict[cj],weakDirichletConditions=False) - def FCTStep(self): - import pdb - rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() - limited_solution = np.zeros((len(rowptr) - 1),'d') - #self.u_free_dof_stage_0_l = np.zeros((len(rowptr) - 1),'d') - #self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage], # soln - #fromFreeToGlobal=0 - #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - # self.offset[0], - # self.stride[0], - # self.dirichletConditions[0].global2freeGlobal_global_dofs, - # self.dirichletConditions[0].global2freeGlobal_free_dofs, - # self.u_free_dof_stage_0_l, - # self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage]) - argsDict = cArgumentsDict.ArgumentsDict() - argsDict["bc_mask"] = self.bc_mask - argsDict["NNZ"] = self.nnz - argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs - argsDict["dt"] = self.timeIntegration.dt - argsDict["lumped_mass_matrix"] = self.ML - argsDict["soln"] = self.sn - argsDict["pn"] = self.u[0].dof - argsDict["solH"] = self.sHigh - argsDict["uLow"] = self.sLow - argsDict["uDotLow"] = self.uDotLow - argsDict["limited_solution"] = limited_solution - argsDict["csrRowIndeces_DofLoops"] = rowptr - argsDict["csrColumnOffsets_DofLoops"] = colind - argsDict["MassMatrix"] = MassMatrix - argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL - argsDict["min_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0]) #cek hack just set from physical bounds - argsDict["max_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0] + self.coefficients.thetaSR_types[0]) #cek hack - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - argsDict["MONOLITHIC"] =0#cek hack self.coefficients.MONOLITHIC - #pdb.set_trace() - self.richards.FCTStep(argsDict) - - # self.nnz, # number of non zero entries - # len(rowptr) - 1, # number of DOFs - # self.timeIntegration.dt, - # self.ML, # Lumped mass matrix - # self.sn, - # self.u_dof_old, - # self.sHigh, # high order solution - # self.sLow, - # limited_solution, - # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) - # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) - # MassMatrix, - # self.dt_times_dC_minus_dL, - # self.min_s_bc, - # self.max_s_bc, - # self.coefficients.LUMPED_MASS_MATRIX, - # self.coefficients.MONOLITHIC) - old_dof = self.u[0].dof.copy() - self.invert(limited_solution, self.u[0].dof) - self.timeIntegration.u[:] = self.u[0].dof - #fromFreeToGlobal=1 #direction copying - #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - # self.offset[0], - # self.stride[0], - # self.dirichletConditions[0].global2freeGlobal_global_dofs, - # self.dirichletConditions[0].global2freeGlobal_free_dofs, - # self.u[0].dof, - # limited_solution) - def kth_FCT_step(self): - #import pdb - #pdb.set_trace() - rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() - limitedFlux = np.zeros(self.nnz) - limited_solution = np.zeros((len(rowptr) - 1),'d') - #limited_solution[:] = self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage] - fromFreeToGlobal=0 #direction copying - cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - self.offset[0], - self.stride[0], - self.dirichletConditions[0].global2freeGlobal_global_dofs, - self.dirichletConditions[0].global2freeGlobal_free_dofs, - limited_solution, - self.timeintegration.u_dof_stage[0][self.timeIntegration.lstage]) - - self.richards.kth_FCT_step( - self.timeIntegration.dt, - self.coefficients.num_fct_iter, - self.nnz, # number of non zero entries - len(rowptr) - 1, # number of DOFs - MassMatrix, - self.ML, # Lumped mass matrix - self.u_dof_old, - limited_solution, - self.uDotLow, - self.uLow, - self.dLow, - self.fluxMatrix, - limitedFlux, - rowptr, - colind) - - self.timeIntegration.u[:] = limited_solution - #self.u[0].dof[:] = limited_solution - fromFreeToGlobal=1 #direction copying - cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - self.offset[0], - self.stride[0], - self.dirichletConditions[0].global2freeGlobal_global_dofs, - self.dirichletConditions[0].global2freeGlobal_free_dofs, - self.u[0].dof, - limited_solution) - def calculateCoefficients(self): - pass - def calculateElementResidual(self): - if self.globalResidualDummy != None: - self.getResidual(self.u[0].dof,self.globalResidualDummy) - def getResidual(self,u,r): - import pdb - import copy - """ - Calculate the element residuals and add in to the global residual - """ - cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, - self.jacobian) - if self.u_dof_old is None: - # Pass initial condition to u_dof_old - self.u_dof_old = np.copy(self.u[0].dof) - rowptr, colind, nzval = self.jacobian.getCSRrepresentation() - nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix - r.fill(0.0) - ######################## - ### COMPUTE C MATRIX ### - ######################## - if self.cterm_global is None: - # since we only need cterm_global to persist, we can drop the other self.'s - self.cterm = {} - self.cterm_a = {} - self.cterm_global = {} - self.cterm_transpose = {} - self.cterm_a_transpose = {} - self.cterm_global_transpose = {} - rowptr, colind, nzval = self.jacobian.getCSRrepresentation() - nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix - di = self.q[('grad(u)', 0)].copy() # direction of derivative - # JACOBIANS (FOR ELEMENT TRANSFORMATION) - self.q[('J')] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nSpace_global, - self.nSpace_global), - 'd') - self.q[('inverse(J)')] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nSpace_global, - self.nSpace_global), - 'd') - self.q[('det(J)')] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element), - 'd') - self.u[0].femSpace.elementMaps.getJacobianValues(self.elementQuadraturePoints, - self.q['J'], - self.q['inverse(J)'], - self.q['det(J)']) - self.q['abs(det(J))'] = np.abs(self.q['det(J)']) - # SHAPE FUNCTIONS - self.q[('w', 0)] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nDOF_test_element[0]), - 'd') - self.q[('w*dV_m', 0)] = self.q[('w', 0)].copy() - self.u[0].femSpace.getBasisValues(self.elementQuadraturePoints, self.q[('w', 0)]) - cfemIntegrals.calculateWeightedShape(self.elementQuadratureWeights[('u', 0)], - self.q['abs(det(J))'], - self.q[('w', 0)], - self.q[('w*dV_m', 0)]) - # GRADIENT OF TEST FUNCTIONS - self.q[('grad(w)', 0)] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nDOF_test_element[0], - self.nSpace_global), - 'd') - self.u[0].femSpace.getBasisGradientValues(self.elementQuadraturePoints, - self.q['inverse(J)'], - self.q[('grad(w)', 0)]) - self.q[('grad(w)*dV_f', 0)] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nDOF_test_element[0], - self.nSpace_global), - 'd') - cfemIntegrals.calculateWeightedShapeGradients(self.elementQuadratureWeights[('u', 0)], - self.q['abs(det(J))'], - self.q[('grad(w)', 0)], - self.q[('grad(w)*dV_f', 0)]) - ########################## - ### LUMPED MASS MATRIX ### - ########################## - # assume a linear mass term - dm = np.ones(self.q[('u', 0)].shape, 'd') - elementMassMatrix = np.zeros((self.mesh.nElements_global, - self.nDOF_test_element[0], - self.nDOF_trial_element[0]), 'd') - cfemIntegrals.updateMassJacobian_weak_lowmem(dm, - self.q[('w', 0)], - self.q[('w*dV_m', 0)], - elementMassMatrix) - self.MC_a = nzval.copy() - self.MC_global = SparseMat(self.nFreeDOF_global[0], - self.nFreeDOF_global[0], - nnz, - self.MC_a, - colind, - rowptr) - cfemIntegrals.zeroJacobian_CSR(self.nnz, self.MC_global) - cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.csrRowIndeces[(0, 0)], - self.csrColumnOffsets[(0, 0)], - elementMassMatrix, - self.MC_global) - self.ML = np.zeros((self.nFreeDOF_global[0],), 'd') - for i in range(self.nFreeDOF_global[0]): - self.ML[i] = self.MC_a[rowptr[i]:rowptr[i + 1]].sum() - np.testing.assert_almost_equal(self.ML.sum(), - self.mesh.volume, - err_msg="Trace of lumped mass matrix should be the domain volume", verbose=True) - for d in range(self.nSpace_global): # spatial dimensions - # C matrices - self.cterm[d] = np.zeros((self.mesh.nElements_global, - self.nDOF_test_element[0], - self.nDOF_trial_element[0]), 'd') - self.cterm_a[d] = nzval.copy() - #self.cterm_a[d] = np.zeros(nzval.size) - self.cterm_global[d] = SparseMat(self.nFreeDOF_global[0], - self.nFreeDOF_global[0], - nnz, - self.cterm_a[d], - colind, - rowptr) - cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global[d]) - di[:] = 0.0 - di[..., d] = 1.0 - cfemIntegrals.updateHamiltonianJacobian_weak_lowmem(di, - self.q[('grad(w)*dV_f', 0)], - self.q[('w', 0)], - self.cterm[d]) # int[(di*grad(wj))*wi*dV] - cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.csrRowIndeces[(0, 0)], - self.csrColumnOffsets[(0, 0)], - self.cterm[d], - self.cterm_global[d]) - # C Transpose matrices - self.cterm_transpose[d] = np.zeros((self.mesh.nElements_global, - self.nDOF_test_element[0], - self.nDOF_trial_element[0]), 'd') - self.cterm_a_transpose[d] = nzval.copy() - self.cterm_global_transpose[d] = SparseMat(self.nFreeDOF_global[0], - self.nFreeDOF_global[0], - nnz, - self.cterm_a_transpose[d], - colind, - rowptr) - cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global_transpose[d]) - di[:] = 0.0 - di[..., d] = -1.0 - cfemIntegrals.updateAdvectionJacobian_weak_lowmem(di, - self.q[('w', 0)], - self.q[('grad(w)*dV_f', 0)], - self.cterm_transpose[d]) # -int[(-di*grad(wi))*wj*dV] - cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.csrRowIndeces[(0, 0)], - self.csrColumnOffsets[(0, 0)], - self.cterm_transpose[d], - self.cterm_global_transpose[d]) - - rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() - else: - Cy = np.zeros(Cx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() - else: - Cz = np.zeros(Cx.shape, 'd') - rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() - else: - CTy = np.zeros(CTx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() - else: - CTz = np.zeros(CTx.shape, 'd') - - # This is dummy. I just care about the csr structure of the sparse matrix - self.dLow = np.zeros(Cx.shape, 'd') - self.fluxMatrix = np.zeros(Cx.shape, 'd') - self.dt_times_dC_minus_dL = np.zeros(Cx.shape, 'd') - nFree = len(rowptr)-1 - self.min_s_bc = np.zeros(nFree, 'd') + 1E10 - self.max_s_bc = np.zeros(nFree, 'd') - 1E10 - self.uDotLow = np.zeros(nFree, 'd') - self.uLow = np.zeros(nFree, 'd') - # - # cek end computationa of cterm_global - # - # cek showing mquezada an example of using cterm_global sparse matrix - # calculation y = c*x where x==1 - # direction=0 - #rowptr, colind, c = self.cterm_global[direction].getCSRrepresentation() - #y = np.zeros((self.nFreeDOF_global[0],),'d') - #x = np.ones((self.nFreeDOF_global[0],),'d') - # ij=0 - # for i in range(self.nFreeDOF_global[0]): - # for offset in range(rowptr[i],rowptr[i+1]): - # j = colind[offset] - # y[i] += c[ij]*x[j] - # ij+=1 - #Load the unknowns into the finite element dof - self.timeIntegration.calculateCoefs() - self.timeIntegration.calculateU(u) - self.setUnknowns(self.timeIntegration.u) - #cek can put in logic to skip of BC's don't depend on t or u - #Dirichlet boundary conditions - self.numericalFlux.setDirichletValues(self.ebqe) - #flux boundary conditions - #cek hack, just using advective flux for flux BC for now - for t,g in list(self.fluxBoundaryConditionsObjectsDict[0].advectiveFluxBoundaryConditionsDict.items()): - self.ebqe[('advectiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) - self.ebqe[('advectiveFlux_bc_flag',0)][t[0],t[1]] = 1 - # for t,g in self.fluxBoundaryConditionsObjectsDict[0].diffusiveFluxBoundaryConditionsDict.iteritems(): - # self.ebqe[('diffusiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) - # self.ebqe[('diffusiveFlux_bc_flag',0)][t[0],t[1]] = 1 - #self.shockCapturing.lag=True - if self.forceStrongConditions: - self.bc_mask = np.ones_like(self.u[0].dof) - for cj in range(len(self.dirichletConditionsForceDOF)): - for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): - self.u[cj].dof[dofN] = g(self.dirichletConditionsForceDOF[cj].DOFBoundaryPointDict[dofN],self.timeIntegration.t) - self.u_dof_old[dofN] = self.u[cj].dof[dofN] - self.bc_mask[dofN] = 0.0 - degree_polynomial = 1 - try: - degree_polynomial = self.u[0].femSpace.order - except: - pass - - argsDict = cArgumentsDict.ArgumentsDict() - if self.forceStrongConditions: - argsDict["bc_mask"] = self.bc_mask - argsDict["dt"] = self.timeIntegration.dt - argsDict["Theta"] = 1.0 - argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi - argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi - argsDict["mesh_dof"] = self.mesh.nodeArray - argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray - argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN - argsDict["mesh_l2g"] = self.mesh.elementNodesArray - argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] - argsDict["u_trial_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi - argsDict["u_test_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi - argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace - argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace - argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] - argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals - argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians - argsDict["nElements_global"] = self.mesh.nElements_global - argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] - argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, - argsDict["isSeepageFace"] = self.coefficients.isSeepageFace - argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] - argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] - argsDict["rho"] = self.coefficients.rho - argsDict["beta"] = self.coefficients.beta - argsDict["gravity"] = self.coefficients.gravity - argsDict["alpha"] = self.coefficients.vgm_alpha_types - argsDict["n"] = self.coefficients.vgm_n_types - argsDict["thetaR"] = self.coefficients.thetaR_types - argsDict["thetaSR"] = self.coefficients.thetaSR_types - argsDict["KWs"] = self.coefficients.Ksw_types - argsDict["useMetrics"] = 0.0 - argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf - argsDict["lag_shockCapturing"] = 0 - argsDict["shockCapturingDiffusion"] = 0.0 - argsDict["sc_uref"] = 0.0 - argsDict["sc_alpha"] = 0.0 - argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g - argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] - argsDict["elementDiameter"] = self.mesh.elementDiametersArray - argsDict["degree_polynomial"] = degree_polynomial - argsDict["u_dof"] = self.u[0].dof - argsDict["u_dof_old"] = self.u_dof_old - argsDict["velocity"] = self.q['velocity'] - argsDict["q_m"] = self.timeIntegration.m_tmp[0] - argsDict["q_u"] = self.q[('u',0)] - argsDict["q_dV"] = self.q[('dV_u',0)] - argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] - argsDict["cfl"] = self.q[('cfl',0)] - argsDict["q_numDiff_u"] = self.q[('cfl',0)] - argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] - argsDict["offset_u"] = self.offset[0] - argsDict["stride_u"] = self.stride[0] - argsDict["globalResidual"] = r - argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global - argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray - argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray - argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray - argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] - argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] - argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] - argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] - argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] - argsDict["ebqe_phi"] = self.ebqe[('u',0)] - argsDict["epsFact"] = 0.0 - argsDict["ebqe_u"] = self.ebqe[('u',0)] - argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] - argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE - # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION - argsDict["cE"] = self.coefficients.cE - argsDict["cK"] = self.coefficients.cK - # PARAMETERS FOR LOG BASED ENTROPY FUNCTION - argsDict["uL"] = self.coefficients.uL - argsDict["uR"] = self.coefficients.uR - # PARAMETERS FOR EDGE VISCOSITY - argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs - argsDict["NNZ"] = self.nnz - argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern - argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) - argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) - argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms - argsDict["globalJacobian"] = self.jacobian.getCSRrepresentation()[2] - # C matrices - argsDict["Cx"] = Cx - argsDict["Cy"] = Cy - argsDict["Cz"] = Cz - argsDict["CTx"] = CTx - argsDict["CTy"] = CTy - argsDict["CTz"] = CTz - argsDict["ML"] = self.ML - argsDict["delta_x_ij"] = self.delta_x_ij - # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE - argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE - # FLUX CORRECTED TRANSPORT - argsDict["dLow"] = self.dLow - argsDict["fluxMatrix"] = self.fluxMatrix - argsDict["uDotLow"] = self.uDotLow - argsDict["uLow"] = self.uLow - argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL - argsDict["min_s_bc"] = self.min_s_bc - argsDict["max_s_bc"] = self.max_s_bc - argsDict["quantDOFs"] = self.quantDOFs - argsDict["sLow"] = self.sLow - argsDict["sn"] = self.sn - if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG - self.calculateResidual = self.richards.calculateResidual - self.calculateJacobian = self.richards.calculateJacobian - else: - self.calculateResidual = self.richards.calculateResidual_entropy_viscosity - self.calculateJacobian = self.richards.calculateMassMatrix - if self.delta_x_ij is None: - self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') - self.calculateResidual(argsDict) - #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] - #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf - #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] - #self.timeIntegration.calculateElementCoefficients(self.q) - if self.forceStrongConditions:# - for cj in range(len(self.dirichletConditionsForceDOF)):# - for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): - r[self.offset[cj]+self.stride[cj]*dofN] = 0 - if self.stabilization: - self.stabilization.accumulateSubgridMassHistory(self.q) - logEvent("Global residual",level=9,data=r) - self.nonlinear_function_evaluations += 1 - if self.globalResidualDummy is None: - self.globalResidualDummy = np.zeros(r.shape,'d') - - def invert(self,u,r): - #u=s - #r=p - import pdb - import copy - """ - Calculate the element residuals and add in to the global residual - """ - self.sHigh[:] = u - rowptr, colind, nzval = self.jacobian.getCSRrepresentation() - nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix - r.fill(0.0) - rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() - else: - Cy = np.zeros(Cx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() - else: - Cz = np.zeros(Cx.shape, 'd') - rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() - else: - CTy = np.zeros(CTx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() - else: - CTz = np.zeros(CTx.shape, 'd') - - # This is dummy. I just care about the csr structure of the sparse matrix - nFree = len(rowptr)-1 - degree_polynomial = 1 - try: - degree_polynomial = self.u[0].femSpace.order - except: - pass - if self.delta_x_ij is None: - self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') - argsDict = cArgumentsDict.ArgumentsDict() - argsDict["dt"] = self.timeIntegration.dt - argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi - argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi - argsDict["mesh_dof"] = self.mesh.nodeArray - argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray - argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN - argsDict["mesh_l2g"] = self.mesh.elementNodesArray - argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] - argsDict["u_trial_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi - argsDict["u_test_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi - argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace - argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace - argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] - argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals - argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians - argsDict["nElements_global"] = self.mesh.nElements_global - argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] - argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, - argsDict["isSeepageFace"] = self.coefficients.isSeepageFace - argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] - argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] - argsDict["rho"] = self.coefficients.rho - argsDict["beta"] = self.coefficients.beta - argsDict["gravity"] = self.coefficients.gravity - argsDict["alpha"] = self.coefficients.vgm_alpha_types - argsDict["n"] = self.coefficients.vgm_n_types - argsDict["thetaR"] = self.coefficients.thetaR_types - argsDict["thetaSR"] = self.coefficients.thetaSR_types - argsDict["KWs"] = self.coefficients.Ksw_types - argsDict["useMetrics"] = 0.0 - argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf - argsDict["lag_shockCapturing"] = 0 - argsDict["shockCapturingDiffusion"] = 0.0 - argsDict["sc_uref"] = 0.0 - argsDict["sc_alpha"] = 0.0 - argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g - argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] - argsDict["elementDiameter"] = self.mesh.elementDiametersArray - argsDict["degree_polynomial"] = degree_polynomial - argsDict["u_dof"] = u#self.u[0].dof - argsDict["u_dof_old"] = self.u[0].dof - argsDict["velocity"] = self.q['velocity'] - argsDict["q_m"] = self.timeIntegration.m_tmp[0] - argsDict["q_u"] = self.q[('u',0)] - argsDict["q_dV"] = self.q[('dV_u',0)] - argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] - argsDict["cfl"] = self.q[('cfl',0)] - argsDict["q_numDiff_u"] = self.q[('cfl',0)] - argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] - argsDict["offset_u"] = self.offset[0] - argsDict["stride_u"] = self.stride[0] - argsDict["globalResidual"] = r - argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global - argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray - argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray - argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray - argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] - argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] - argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] - argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] - argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] - argsDict["ebqe_phi"] = self.ebqe[('u',0)] - argsDict["epsFact"] = 0.0 - argsDict["ebqe_u"] = self.ebqe[('u',0)] - argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] - argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE - # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION - argsDict["cE"] = self.coefficients.cE - argsDict["cK"] = self.coefficients.cK - # PARAMETERS FOR LOG BASED ENTROPY FUNCTION - argsDict["uL"] = self.coefficients.uL - argsDict["uR"] = self.coefficients.uR - # PARAMETERS FOR EDGE VISCOSITY - argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs - argsDict["NNZ"] = self.nnz - argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern - argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) - argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) - argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms - # C matrices - argsDict["Cx"] = Cx - argsDict["Cy"] = Cy - argsDict["Cz"] = Cz - argsDict["CTx"] = CTx - argsDict["CTy"] = CTy - argsDict["CTz"] = CTz - argsDict["ML"] = self.ML - argsDict["delta_x_ij"] = self.delta_x_ij - # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE - argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE - # FLUX CORRECTED TRANSPORT - argsDict["dLow"] = self.dLow - argsDict["fluxMatrix"] = self.fluxMatrix - argsDict["uDotLow"] = self.uDotLow - argsDict["uLow"] = self.uLow - argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL - argsDict["min_s_bc"] = self.min_s_bc - argsDict["max_s_bc"] = self.max_s_bc - argsDict["quantDOFs"] = self.quantDOFs - argsDict["sLow"] = self.sLow - argsDict["sn"] = self.sn - self.richards.invert(argsDict) - # self.timeIntegration.dt, - # self.u[0].femSpace.elementMaps.psi, - # self.u[0].femSpace.elementMaps.grad_psi, - # self.mesh.nodeArray, - # self.mesh.nodeVelocityArray, - # self.MOVING_DOMAIN, - # self.mesh.elementNodesArray, - # self.elementQuadratureWeights[('u',0)], - # self.u[0].femSpace.psi, - # self.u[0].femSpace.grad_psi, - # self.u[0].femSpace.psi, - # self.u[0].femSpace.grad_psi, - # #element boundary - # self.u[0].femSpace.elementMaps.psi_trace, - # self.u[0].femSpace.elementMaps.grad_psi_trace, - # self.elementBoundaryQuadratureWeights[('u',0)], - # self.u[0].femSpace.psi_trace, - # self.u[0].femSpace.grad_psi_trace, - # self.u[0].femSpace.psi_trace, - # self.u[0].femSpace.grad_psi_trace, - # self.u[0].femSpace.elementMaps.boundaryNormals, - # self.u[0].femSpace.elementMaps.boundaryJacobians, - # #physics - # self.mesh.nElements_global, - # self.ebqe['penalty'],#double* ebqe_penalty_ext, - # self.mesh.elementMaterialTypes,#int* elementMaterialTypes, - # self.coefficients.isSeepageFace, - # self.coefficients.sdInfo[(0,0)][0],#int* a_rowptr, - # self.coefficients.sdInfo[(0,0)][1],#int* a_colind, - # self.coefficients.rho,#double rho, - # self.coefficients.beta,#double beta, - # self.coefficients.gravity,#double* gravity, - # self.coefficients.vgm_alpha_types,#double* alpha, - # self.coefficients.vgm_n_types,#double* n, - # self.coefficients.thetaR_types,#double* thetaR, - # self.coefficients.thetaSR_types,#double* thetaSR, - # self.coefficients.Ksw_types,#double* KWs, - # False,#self.coefficients.useMetrics, - # self.timeIntegration.alpha_bdf, - # 0,#self.shockCapturing.lag, - # 0.0,#cek hack self.shockCapturing.shockCapturingFactor, - # 0.0,#self.coefficients.sc_uref, - # 0.0,#self.coefficients.sc_beta, - # self.u[0].femSpace.dofMap.l2g, - # self.l2g[0]['freeGlobal'], - # self.mesh.elementDiametersArray, - # degree_polynomial, - # self.sHigh, - # self.u_dof_old, - # self.q['velocity'],#self.coefficients.q_v, - # self.timeIntegration.m_tmp[0], - # self.q[('u',0)], - # self.timeIntegration.beta_bdf[0], - # self.q[('cfl',0)], - # self.edge_based_cfl, - # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff[0], - # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff_last[0], - # self.offset[0],self.stride[0], - # r, - # self.mesh.nExteriorElementBoundaries_global, - # self.mesh.exteriorElementBoundariesArray, - # self.mesh.elementBoundaryElementsArray, - # self.mesh.elementBoundaryLocalElementBoundariesArray, - # self.ebqe['velocity'],#self.coefficients.ebqe_v, - # self.numericalFlux.isDOFBoundary[0], - # self.numericalFlux.ebqe[('u',0)], - # self.ebqe[('advectiveFlux_bc_flag',0)], - # self.ebqe[('advectiveFlux_bc',0)], - # self.ebqe[('u',0)],#cek hack self.coefficients.ebqe_phi, - # 0.0,#cek hack self.coefficients.epsFact, - # self.ebqe[('u',0)], - # self.ebqe[('advectiveFlux',0)], - # # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION - # self.coefficients.cE, - # self.coefficients.cK, - # # PARAMETERS FOR LOG BASED ENTROPY FUNCTION - # self.coefficients.uL, - # self.coefficients.uR, - # # PARAMETERS FOR EDGE VISCOSITY - # len(rowptr) - 1, # num of DOFs - # len(Cx), # num of non-zero entries in the sparsity pattern - # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) - # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) - # self.csrRowIndeces[(0, 0)], # row indices (convenient for element loops) - # self.csrColumnOffsets[(0, 0)], # column indices (convenient for element loops) - # self.csrColumnOffsets_eb[(0, 0)], # indices for boundary terms - # # C matrices - # Cx, - # Cy, - # Cz, - # CTx, - # CTy, - # CTz, - # self.ML, - # self.delta_x_ij, - # # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - # self.coefficients.LUMPED_MASS_MATRIX, - # self.coefficients.STABILIZATION_TYPE, - # self.coefficients.ENTROPY_TYPE, - # # FLUX CORRECTED TRANSPORT - # self.dLow, - # self.fluxMatrix, - # self.uDotLow, - # self.uLow, - # self.dt_times_dC_minus_dL, - # self.min_s_bc, - # self.max_s_bc, - # self.quantDOFs) - #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] - #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf - #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] - #self.timeIntegration.calculateElementCoefficients(self.q) - #if self.forceStrongConditions:# - # for cj in range(len(self.dirichletConditionsForceDOF)):# - # for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): - # r[self.offset[cj]+self.stride[cj]*dofN] = 0 - #if self.stabilization: - # self.stabilization.accumulateSubgridMassHistory(self.q) - #logEvent("Global residual",level=9,data=r) - #self.nonlinear_function_evaluations += 1 - #if self.globalResidualDummy is None: - # self.globalResidualDummy = numpy.zeros(r.shape,'d') - def getJacobian(self,jacobian): - if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG - cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, - jacobian) - degree_polynomial = 1 - try: - degree_polynomial = self.u[0].femSpace.order - except: - pass - if self.delta_x_ij is None: - self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') - argsDict = cArgumentsDict.ArgumentsDict() - argsDict["dt"] = self.timeIntegration.dt - argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi - argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi - argsDict["mesh_dof"] = self.mesh.nodeArray - argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray - argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN - argsDict["mesh_l2g"] = self.mesh.elementNodesArray - argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] - argsDict["u_trial_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi - argsDict["u_test_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi - argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace - argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace - argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] - argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals - argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians - argsDict["nElements_global"] = self.mesh.nElements_global - argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] - argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, - argsDict["isSeepageFace"] = self.coefficients.isSeepageFace - argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] - argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] - argsDict["rho"] = self.coefficients.rho - argsDict["beta"] = self.coefficients.beta - argsDict["gravity"] = self.coefficients.gravity - argsDict["alpha"] = self.coefficients.vgm_alpha_types - argsDict["n"] = self.coefficients.vgm_n_types - argsDict["thetaR"] = self.coefficients.thetaR_types - argsDict["thetaSR"] = self.coefficients.thetaSR_types - argsDict["KWs"] = self.coefficients.Ksw_types - argsDict["useMetrics"] = 0.0 - argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf - argsDict["lag_shockCapturing"] = 0 - argsDict["shockCapturingDiffusion"] = 0.0 - argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g - argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] - argsDict["elementDiameter"] = self.mesh.elementDiametersArray - argsDict["degree_polynomial"] = degree_polynomial - argsDict["u_dof"] = self.u[0].dof - argsDict["velocity"] = self.q['velocity'] - argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] - argsDict["cfl"] = self.q[('cfl',0)] - argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] - argsDict["csrRowIndeces_u_u"] = self.csrRowIndeces[(0,0)] - argsDict["csrColumnOffsets_u_u"] = self.csrColumnOffsets[(0,0)] - argsDict["globalJacobian"] = jacobian.getCSRrepresentation()[2] - argsDict["delta_x_ij"] = self.delta_x_ij - argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global - argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray - argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray - argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray - argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] - argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] - argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] - argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] - argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] - argsDict["csrColumnOffsets_eb_u_u"] = self.csrColumnOffsets_eb[(0,0)] - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - self.calculateJacobian(argsDict) - if self.forceStrongConditions: - for dofN in list(self.dirichletConditionsForceDOF[0].DOFBoundaryConditionsDict.keys()): - global_dofN = self.offset[0]+self.stride[0]*dofN - self.nzval[np.where(self.colind == global_dofN)] = 0.0 #column - self.nzval[self.rowptr[global_dofN]:self.rowptr[global_dofN+1]] = 0.0 #row - zeroRow=True - for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]):#row - if (self.colind[i] == global_dofN): - self.nzval[i] = 1.0 - zeroRow = False - if zeroRow: - raise RuntimeError("Jacobian has a zero row because sparse matrix has no diagonal entry at row "+repr(global_dofN)+". You probably need add diagonal mass or reaction term") - #scaling = 1.0#probably want to add some scaling to match non-dirichlet diagonals in linear system - #for cj in range(self.nc): - # for dofN in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.keys()): - # global_dofN = self.offset[cj]+self.stride[cj]*dofN - # for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]): - # if (self.colind[i] == global_dofN): - # self.nzval[i] = scaling - # else: - # self.nzval[i] = 0.0 - logEvent("Jacobian ",level=10,data=jacobian) - #mwf decide if this is reasonable for solver statistics - self.nonlinear_function_jacobian_evaluations += 1 - return jacobian - def calculateElementQuadrature(self): - """ - Calculate the physical location and weights of the quadrature rules - and the shape information at the quadrature points. - - This function should be called only when the mesh changes. - """ - #self.u[0].femSpace.elementMaps.getValues(self.elementQuadraturePoints, - # self.q['x']) - self.u[0].femSpace.elementMaps.getBasisValuesRef(self.elementQuadraturePoints) - self.u[0].femSpace.elementMaps.getBasisGradientValuesRef(self.elementQuadraturePoints) - self.u[0].femSpace.getBasisValuesRef(self.elementQuadraturePoints) - self.u[0].femSpace.getBasisGradientValuesRef(self.elementQuadraturePoints) - self.coefficients.initializeElementQuadrature(self.timeIntegration.t,self.q) - if self.stabilization != None: - self.stabilization.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) - self.stabilization.initializeTimeIntegration(self.timeIntegration) - if self.shockCapturing != None: - self.shockCapturing.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) - def calculateElementBoundaryQuadrature(self): - pass - def calculateExteriorElementBoundaryQuadrature(self): - """ - Calculate the physical location and weights of the quadrature rules - and the shape information at the quadrature points on global element boundaries. - - This function should be called only when the mesh changes. - """ - # - #get physical locations of element boundary quadrature points - # - #assume all components live on the same mesh - self.u[0].femSpace.elementMaps.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.elementMaps.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.elementMaps.getValuesGlobalExteriorTrace(self.elementBoundaryQuadraturePoints, - self.ebqe['x']) - self.fluxBoundaryConditionsObjectsDict = dict([(cj,FluxBoundaryConditions(self.mesh, - self.nElementBoundaryQuadraturePoints_elementBoundary, - self.ebqe[('x')], - getAdvectiveFluxBoundaryConditions=self.advectiveFluxBoundaryConditionsSetterDict[cj], - getDiffusiveFluxBoundaryConditions=self.diffusiveFluxBoundaryConditionsSetterDictDict[cj])) - for cj in list(self.advectiveFluxBoundaryConditionsSetterDict.keys())]) - self.coefficients.initializeGlobalExteriorElementBoundaryQuadrature(self.timeIntegration.t,self.ebqe) - def estimate_mt(self): - pass - def calculateSolutionAtQuadrature(self): - pass - def calculateAuxiliaryQuantitiesAfterStep(self): - pass diff --git a/richards_fct/richards/__init__.py b/richards_fct/richards/__init__.py deleted file mode 100644 index c45e66de51..0000000000 --- a/richards_fct/richards/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -""" -Modules for simulating variably saturated single-phase flow -""" - -__all__ = ["Richards", - "cRichards"] diff --git a/richards_fct/richards/cRichards.cpp b/richards_fct/richards/cRichards.cpp deleted file mode 100644 index 21c500c55c..0000000000 --- a/richards_fct/richards/cRichards.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "pybind11/pybind11.h" -#include "pybind11/stl_bind.h" - -#define FORCE_IMPORT_ARRAY -#include "Richards.h" - -#if defined(__GNUC__) && !defined(__clang__) - namespace workaround - { - inline void define_allocators() - { - std::allocator a0; - std::allocator a1; - } - } -#endif - - -namespace py = pybind11; -using proteus::Richards_base; -PYBIND11_MODULE(cRichards, m) -{ - xt::import_numpy(); - - py::class_(m, "cRichards_base") - .def(py::init(&proteus::newRichards)) - .def("calculateResidual", &Richards_base::calculateResidual) - .def("calculateJacobian", &Richards_base::calculateJacobian) - .def("invert", &Richards_base::invert) - .def("FCTStep", &Richards_base::FCTStep) - .def("kth_FCT_step", &Richards_base::kth_FCT_step) - .def("calculateResidual_entropy_viscosity", &Richards_base::calculateResidual_entropy_viscosity) - .def("calculateMassMatrix", &Richards_base::calculateMassMatrix); -} - - diff --git a/richards_fct/richards/edit/Richards.h.save b/richards_fct/richards/edit/Richards.h.save deleted file mode 100755 index 865f4cbb34..0000000000 --- a/richards_fct/richards/edit/Richards.h.save +++ /dev/null @@ -1,2967 +0,0 @@ -#ifndef Richards_H -#define Richards_H -#include -#include -#include -#include "CompKernel.h" -#include "ModelFactory.h" -#include "../mprans/ArgumentsDict.h" -#include "xtensor-python/pyarray.hpp" -#define nnz nSpace - -namespace py = pybind11; -#define POWER_SMOOTHNESS_INDICATOR 2 -#define IS_BETAij_ONE 0 -#define GLOBAL_FCT 0 -namespace proteus -{ - // Power entropy // - inline double ENTROPY(const double& phi, const double& phiL, const double& phiR){ - return 1./2.*std::pow(fabs(phi),2.); - } - inline double DENTROPY(const double& phi, const double& phiL, const double& phiR){ - return fabs(phi)*(phi>=0 ? 1 : -1); - } - // Log entropy // for level set from 0 to 1 - inline double ENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ - return std::log(fabs((phi-phiL)*(phiR-phi))+1E-14); - } - inline double DENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ - return (phiL+phiR-2*phi)*((phi-phiL)*(phiR-phi)>=0 ? 1 : -1)/(fabs((phi-phiL)*(phiR-phi))+1E-14); - } -} - -namespace proteus -{ - class Richards_base - { - //The base class defining the interface - public: - virtual ~Richards_base(){} - virtual void calculateResidual(arguments_dict& args)=0; - virtual void calculateJacobian(arguments_dict& args)=0; - virtual void invert(arguments_dict& args)=0; - virtual void FCTStep(arguments_dict& args)=0; - virtual void kth_FCT_step(arguments_dict& args)=0; - virtual void calculateResidual_entropy_viscosity(arguments_dict& args)=0; - virtual void calculateMassMatrix(arguments_dict& args)=0; - }; - - template - class Richards : public Richards_base - { - public: - const int nDOF_test_X_trial_element; - CompKernelType ck; - Richards(): - nDOF_test_X_trial_element(nDOF_test_element*nDOF_trial_element), - ck() - {} - inline - void evaluateCoefficients(const int rowptr[nSpace], - const int colind[nnz], - const double rho, - const double beta, - const double gravity[nSpace], - const double alpha, - const double n_vg, - const double thetaR, - const double thetaSR, - const double KWs[nnz], - const double& u, - double& m, - double& dm, - double f[nSpace], - double df[nSpace], - double a[nnz], - double da[nnz], - double as[nnz], - double& kr, - double& dkr) - { - const int nSpace2 = nSpace * nSpace; - double psiC; - double pcBar; - double pcBar_n; - double pcBar_nM1; - double pcBar_nM2; - double onePlus_pcBar_n; - double sBar; - double sqrt_sBar; - double DsBar_DpsiC; - double thetaW; - double DthetaW_DpsiC; - double vBar; - double vBar2; - double DvBar_DpsiC; - double KWr; - double DKWr_DpsiC; - double rho2 = rho * rho; - double thetaS; - double rhom; - double drhom; - double m_vg; - double pcBarStar; - double sqrt_sBarStar; - - psiC = -u; - m_vg = 1.0 - 1.0 / n_vg; - thetaS = thetaR + thetaSR; - if (psiC > 0.0) - { - pcBar = alpha * psiC; - pcBarStar = pcBar; - if (pcBar < 1.0e-8) - pcBarStar = 1.0e-8; - pcBar_nM2 = pow(pcBarStar, n_vg - 2); - pcBar_nM1 = pcBar_nM2 * pcBar; - pcBar_n = pcBar_nM1 * pcBar; - onePlus_pcBar_n = 1.0 + pcBar_n; - - sBar = pow(onePlus_pcBar_n, -m_vg); - /* using -mn = 1-n */ - DsBar_DpsiC = alpha * (1.0 - n_vg) * (sBar/onePlus_pcBar_n)*pcBar_nM1; - - vBar = 1.0-pcBar_nM1*sBar; - vBar2 = vBar*vBar; - DvBar_DpsiC = -alpha*(n_vg-1.0)*pcBar_nM2*sBar - pcBar_nM1*DsBar_DpsiC; - - thetaW = thetaSR*sBar + thetaR; - DthetaW_DpsiC = thetaSR * DsBar_DpsiC; - - sqrt_sBar = sqrt(sBar); - sqrt_sBarStar = sqrt_sBar; - if (sqrt_sBar < 1.0e-8) - sqrt_sBarStar = 1.0e-8; - KWr= sqrt_sBar*vBar2; - DKWr_DpsiC= ((0.5/sqrt_sBarStar)*DsBar_DpsiC*vBar2 - + - 2.0*sqrt_sBar*vBar*DvBar_DpsiC); - } - else - { - thetaW = thetaS; - DthetaW_DpsiC = 0.0; - KWr = 1.0; - DKWr_DpsiC = 0.0; - } - //slight compressibility - rhom = rho*exp(beta*u); - drhom = beta*rhom; - m = rhom*thetaW; - dm = -rhom*DthetaW_DpsiC+drhom*thetaW; - for (int I=0;I thetaS || thetaW <= thetaR) - { - //cek debug - std::cout<<"rho "< 0.0) - { - isDOFBoundary = 1; - bc_u = bc_u_seepage; - } - else - { - isDOFBoundary = 0; - flux = 0.0; - } - } - /* //set DOF flag and flux correctly if seepage face */ - /* if (isSeepageFace) */ - /* { */ - /* if (flux < 0.0 || u < bc_u_seepage) */ - /* { */ - /* isDOFBoundary = 0; */ - /* flux = 0.0; */ - /* } */ - /* else */ - /* { */ - /* isDOFBoundary = 1; */ - /* bc_u = bc_u_seepage; */ - /* } */ - /* } */ - /* //Dirichlet penalty */ - /* if (isDOFBoundary) */ - /* flux += penalty*(u-bc_u); */ - } - else - flux = bc_flux; - } - - void exteriorNumericalFluxJacobian(const int rowptr[nSpace], - const int colind[nnz], - const int isDOFBoundary, - const double n[nSpace], - const double K[nnz], - const double dK[nnz], - const double grad_psi[nSpace], - const double grad_v[nSpace], - const double dK_rho_g[nSpace], - const double v, - const double penalty, - double& fluxJacobian) - { - if (isDOFBoundary) - { - fluxJacobian = 0.0; - for(int I=0;I& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - double sc_uref = args.scalar("sc_uref"); - double sc_alpha = args.scalar("sc_alpha"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& u_dof_old = args.array("u_dof_old"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m = args.array("q_m"); - xt::pyarray& q_u = args.array("q_u"); - xt::pyarray& q_dV = args.array("q_dV"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - int offset_u = args.scalar("offset_u"); - int stride_u = args.scalar("stride_u"); - xt::pyarray& globalResidual = args.array("globalResidual"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& ebqe_phi = args.array("ebqe_phi"); - double epsFact = args.scalar("epsFact"); - xt::pyarray& ebqe_u = args.array("ebqe_u"); - xt::pyarray& ebqe_flux = args.array("ebqe_flux"); - // PARAMETERS FOR EDGE BASED STABILIZATION - double cE = args.scalar("cE"); - double cK = args.scalar("cK"); - // PARAMETERS FOR LOG BASED ENTROPY FUNCTION - double uL = args.scalar("uL"); - double uR = args.scalar("uR"); - // PARAMETERS FOR EDGE VISCOSITY - int numDOFs = args.scalar("numDOFs"); - int NNZ = args.scalar("NNZ"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); - xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); - xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); - xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); - // C matrices - xt::pyarray& Cx = args.array("Cx"); - xt::pyarray& Cy = args.array("Cy"); - xt::pyarray& Cz = args.array("Cz"); - xt::pyarray& CTx = args.array("CTx"); - xt::pyarray& CTy = args.array("CTy"); - xt::pyarray& CTz = args.array("CTz"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); - int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); - // FOR FCT - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& fluxMatrix = args.array("fluxMatrix"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); - xt::pyarray& min_s_bc = args.array("min_s_bc"); - xt::pyarray& max_s_bc = args.array("max_s_bc"); - // AUX QUANTITIES OF INTEREST - xt::pyarray& quantDOFs = args.array("quantDOFs"); - xt::pyarray& sLow = args.array("sLow"); - xt::pyarray& sn = args.array("sn"); - - assert(a_rowptr.data()[nSpace] == nnz); - assert(a_rowptr.data()[nSpace] == nSpace); - //cek should this be read in? - double Ct_sge = 4.0; - - //loop over elements to compute volume integrals and load them into element and global residual - // - //eN is the element index - //eN_k is the quadrature point index for a scalar - //eN_k_nSpace is the quadrature point index for a vector - //eN_i is the element test function index - //eN_j is the element trial function index - //eN_k_j is the quadrature point index for a trial function - //eN_k_i is the quadrature point index for a trial function - for(int eN=0;eN& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); - xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); - xt::pyarray& globalJacobian = args.array("globalJacobian"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - assert(a_rowptr.data()[nSpace] == nnz); - assert(a_rowptr.data()[nSpace] == nSpace); - double Ct_sge = 4.0; - - // - //loop over elements to compute volume integrals and load them into the element Jacobians and global Jacobian - // - for(int eN=0;eN& bc_mask = args.array("bc_mask"); - int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern - int numDOFs = args.scalar("numDOFs"); //number of DOFs - double dt = args.scalar("dt"); - xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) - xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn - xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn - xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& limited_solution = args.array("limited_solution"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets - xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices - xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 - xt::pyarray& max_s_bc = args.array("max_s_bc"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int MONOLITHIC = args.scalar("MONOLITHIC"); - register double Rpos[numDOFs], Rneg[numDOFs]; - register double FluxCorrectionMatrix[NNZ]; - register double solL[numDOFs]; - register double sdot[numDOFs]; - ////////////////// - // LOOP in DOFs // - ////////////////// - int ij=0; - for (int i=0; i 0) ? 1. : 0.); - Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); - - //update ij - ij+=1; - //std::cout<<"sdoti error"<0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])) - * FluxCorrectionMatrix[ij]; - alpha_dot = fmin(1.0, beta_ij*fabs(alpha_fA)/MassMatrix.data()[ij]/fmax(1.0e-8,fabs(sdoti-sdotj))); - if (MONOLITHIC == 0) - { - ith_Limiter_times_FluxCorrectionMatrix += alpha_fA; - } - else - { - ith_Limiter_times_FluxCorrectionMatrix += alpha_fA + (LUMPED_MASS_MATRIX == 1 ? 0. : 1.)*dt*alpha_dot*MassMatrix.data()[ij]*(sdoti-sdotj); - } - //update ij - ij+=1; - } - limited_solution.data()[i] = solL[i] + 1./lumped_mass_matrix.data()[i]*ith_Limiter_times_FluxCorrectionMatrix*bc_mask[i]; - } - } - - void kth_FCT_step(arguments_dict& args) - { - int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern - int numDOFs = args.scalar("numDOFs"); //number of DOFs - int num_fct_iter = args.scalar("num_fct_iter"); - double dt = args.scalar("dt"); - xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) - xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn - xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn - xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& solLim = args.array("limited_solution"); - xt::pyarray& MC = args.array("MC"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& FluxMatrix = args.array("FluxMatrix"); - xt::pyarray& limitedFlux = args.array("limited_Flux"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets - xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices - xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 - xt::pyarray& max_s_bc = args.array("max_s_bc"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int MONOLITHIC = args.scalar("MONOLITHIC"); - register double Rpos[numDOFs], Rneg[numDOFs]; - int ij=0; - - ////////////////////////////////////////////////////// - // ********** COMPUTE LOW ORDER SOLUTION ********** // - ////////////////////////////////////////////////////// - if (num_fct_iter == 0) - { // No FCT for global bounds - for (int i=0; i 0) ? 1. : 0.); - // update ij - ij+=1; - } - // compute Q vectors - double mi = ML.data()[i]; - double solLimi = solLim.data()[i]; - double Qposi = mi*(maxi-solLimi); - // compute R vectors - Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - } - ij=0; - for (int i=0; i0 ? Rposi : Rpos[j]); - // compute limited flux - ith_Limiter_times_FluxCorrectionMatrix += Lij*Fluxij; - - // update limited flux - limitedFlux.data()[ij] = Lij*Fluxij; - - //update FluxMatrix - FluxMatrix.data()[ij] = Fluxij; - - //update ij - ij+=1; - } - //update limited solution - double mi = ML.data()[i]; - solLim.data()[i] += 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; - } - } - } - - // ***************************************** // - // ********** HIGH ORDER SOLUTION ********** // - // ***************************************** // - ij=0; - for (int i=0; i 0 ? 1. : 0.); - Pnegi += fij * (fij < 0 ? 1. : 0.); - //update ij - ij+=1; - } - // compute Q vectors // - double mi = ML.data()[i]; - double Qposi = mi*(maxi-solLim.data()[i]); - double Qnegi = mi*(mini-solLim.data()[i]); - // compute R vectors // - Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); - } - - // COMPUTE LIMITERS // - ij=0; - for (int i=0; i 0 ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j]); - // compute ith_limited_flux_correction - ith_limited_flux_correction += Lij*fij; - ij+=1; - } - double mi = ML.data()[i]; - solLim[i] += 1./mi*ith_limited_flux_correction; - } - } - - void calculateResidual_entropy_viscosity(arguments_dict& args) - { - xt::pyarray& globalJacobian = args.array("globalJacobian"); - double Theta = args.scalar("Theta"); - xt::pyarray& bc_mask = args.array("bc_mask"); - double dt = args.scalar("dt"); - xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - double sc_uref = args.scalar("sc_uref"); - double sc_alpha = args.scalar("sc_alpha"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& r_l2g = args.array("r_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - int degree_polynomial = args.scalar("degree_polynomial"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& u_dof_old = args.array("u_dof_old"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m = args.array("q_m"); - xt::pyarray& q_u = args.array("q_u"); - xt::pyarray& q_dV = args.array("q_dV"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - int offset_u = args.scalar("offset_u"); - int stride_u = args.scalar("stride_u"); - xt::pyarray& globalResidual = args.array("globalResidual"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& ebqe_phi = args.array("ebqe_phi"); - double epsFact = args.scalar("epsFact"); - xt::pyarray& ebqe_u = args.array("ebqe_u"); - xt::pyarray& ebqe_flux = args.array("ebqe_flux"); - // PARAMETERS FOR EDGE BASED STABILIZATION - double cE = args.scalar("cE"); - double cK = args.scalar("cK"); - // PARAMETERS FOR LOG BASED ENTROPY FUNCTION - double uL = args.scalar("uL"); - double uR = args.scalar("uR"); - // PARAMETERS FOR EDGE VISCOSITY - int numDOFs = args.scalar("numDOFs"); - int NNZ = args.scalar("NNZ"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); - xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); - xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); - xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); - // C matrices - xt::pyarray& Cx = args.array("Cx"); - xt::pyarray& Cy = args.array("Cy"); - xt::pyarray& Cz = args.array("Cz"); - xt::pyarray& CTx = args.array("CTx"); - xt::pyarray& CTy = args.array("CTy"); - xt::pyarray& CTz = args.array("CTz"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); - int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); - // FOR FCT - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& fluxMatrix = args.array("fluxMatrix"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); - xt::pyarray& min_s_bc = args.array("min_s_bc"); - xt::pyarray& max_s_bc = args.array("max_s_bc"); - // AUX QUANTITIES OF INTEREST - xt::pyarray& quantDOFs = args.array("quantDOFs"); - xt::pyarray& sLow = args.array("sLow"); - xt::pyarray& sn = args.array("sn"); - register double Rpos[numDOFs], Rneg[numDOFs]; - //register double FluxCorrectionMatrix[NNZ]; - // NOTE: This function follows a different (but equivalent) implementation of the smoothness based indicator than NCLS.h - // Allocate space for the transport matrices - // This is used for first order KUZMIN'S METHOD - register double TransportMatrix[NNZ],TransportMatrixConsistent[NNZ]; - register double TransportMatrixn[NNZ],TransportMatrixConsistentn[NNZ]; - std::valarray u_free_dof(numDOFs); - std::valarray u_free_dof_old(numDOFs); - std::valarray ML2(numDOFs); - for(int eN=0;eN= 0 && isFluxBoundary_u[ebNE_kb] != 1 ) //outflow. This is handled via the transport matrices. Then flux_ext=0 and dflux_ext!=0 */ - /* { */ - /* dflux_ext = flow; */ - /* flux_ext = 0; */ - /* // save external u */ - /* ebqe_u[ebNE_kb] = u_ext; */ - /* } */ - /* else // inflow. This is handled via the boundary integral. Then flux_ext!=0 and dflux_ext=0 */ - /* { */ - /* dflux_ext = 0; */ - /* // save external u */ - /* ebqe_u[ebNE_kb] = isDOFBoundary_u[ebNE_kb]*ebqe_bc_u_ext[ebNE_kb]+(1-isDOFBoundary_u[ebNE_kb])*u_ext; */ - /* if (isDOFBoundary_u[ebNE_kb] == 1) */ - /* flux_ext = ebqe_bc_u_ext[ebNE_kb]*flow; */ - /* else if (isFluxBoundary_u[ebNE_kb] == 1) */ - /* flux_ext = ebqe_bc_flux_u_ext[ebNE_kb]; */ - /* else */ - /* { */ - /* std::cout<<"warning: VOF open boundary with no external trace, setting to zero for inflow"<= 0.) - { - alpha_numerator_pos += alpha_num; - alpha_denominator_pos += alpha_num; - } - else - { - alpha_numerator_neg += alpha_num; - alpha_denominator_neg += fabs(alpha_num); - } - //update ij - ij+=1; - } - // scale g vector by lumped mass matrix - if (fabs(ML.data()[i] - ML2[i]) > 1.0e-16) - std::cout<<"ML "< 0.0) - // assert( (xi[I] - xj[I]) == delta_x_ij[offset*3+I]); - //gi_times_x += gi[I]*(xi[I]-xj[I]); - gi_times_x += gi[I]*delta_x_ij.data()[offset*3+I]; - } - // compute the positive and negative part of gi*(xi-xj) - SumPos += gi_times_x > 0 ? gi_times_x : 0; - SumNeg += gi_times_x < 0 ? gi_times_x : 0; - } - double sigmaPosi = fmin(1.,(fabs(SumNeg)+1E-15)/(SumPos+1E-15)); - double sigmaNegi = fmin(1.,(SumPos+1E-15)/(fabs(SumNeg)+1E-15)); - double alpha_numi = fabs(sigmaPosi*alpha_numerator_pos + sigmaNegi*alpha_numerator_neg); - double alpha_deni = sigmaPosi*alpha_denominator_pos + sigmaNegi*alpha_denominator_neg; - if (IS_BETAij_ONE == 1) - { - alpha_numi = fabs(alpha_numerator_pos + alpha_numerator_neg); - alpha_deni = alpha_denominator_pos + alpha_denominator_neg; - } - double alphai = alpha_numi/(alpha_deni+1E-15); - quantDOFs.data()[i] = alphai; - - if (POWER_SMOOTHNESS_INDICATOR==0) - psi[i] = 1.0; - else - psi[i] = std::pow(alphai,POWER_SMOOTHNESS_INDICATOR); //NOTE: they use alpha^2 in the paper - } - ///////////////////////////////////////////// - // ** LOOP IN DOFs FOR EDGE BASED TERMS ** // - ///////////////////////////////////////////// - ij=0; - for (int i=0; i Dissipation matrices as well. - double soli = u_free_dof[i]; // solution at time tn for the ith DOF - double solni = u_free_dof_old[i]; // solution at time tn for the ith DOF - for (int I=0;I mMax) - { - std::cout<<"mass out of bounds "< 0) ? 1. : 0.); - // Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); - // ij+=1; - // } - // double mi = ML[i]; - // double solni = u_dof_old[i]; - // double Qposi = mi*(maxi-solni); - // double Qnegi = mi*(mini-solni); - - //std::cout << Qposi << std::endl; - // Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - // Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); - - //if (Rpos[i] < 0) - //{ - // std::cout << mi << "\t" << maxi << "\t" << solni << std::endl; - // std::cout << Qposi << "\t" << Pposi << std::endl; - // std::cout << Rpos[i] << std::endl; - //abort(); - //} - //} - - //ij=0; - //for (int i=0; i 1.0 || Rposi < 0.0) - //std::cout << "Rposi: " << Rposi << std::endl; - //if (Rnegi > 1.0 || Rnegi < 0.0) - //std::cout << "Rnegi: " << Rnegi << std::endl; - - // LOOP OVER THE SPARSITY PATTERN (j-LOOP)// - // for (int offset=csrRowIndeces_DofLoops.data()[i]; - // offset0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])); - // //Lij=0.0; - // ith_Limiter_times_FluxCorrectionMatrix += Lij*FluxCorrectionMatrix[ij]; - // //update ij - // ij+=1; - // } - // double mi = ML[i]; - // double solni = u_dof_old[i]; - // globalResidual[i] = solni + 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; - //} - - } - - void invert(arguments_dict& args) - { - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - xt::pyarray& globalResidual = args.array("globalResidual"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - int numDOFs = args.scalar("numDOFs"); - for (int i=0; i mMax) - { - std::cout<<"mass out of bounds "<("dt"); - xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - //element boundary - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - //physics - int nElements_global = args.scalar("nElements_global"); - //new - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - //end new - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& r_l2g = args.array("r_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - int degree_polynomial = args.scalar("degree_polynomial"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); - xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); - xt::pyarray& globalJacobian = args.array("globalJacobian"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - //std::cout<<"ndjaco address "<(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - else if (nSpaceIn == 2) - return proteus::chooseAndAllocateDiscretization2D(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - else - { - assert(nSpaceIn == 3); - return proteus::chooseAndAllocateDiscretization(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - } - } -}//proteus -#endif \ No newline at end of file diff --git a/richards_fct/richards/edit/Richards.h.save.1 b/richards_fct/richards/edit/Richards.h.save.1 deleted file mode 100755 index bda6e99948..0000000000 --- a/richards_fct/richards/edit/Richards.h.save.1 +++ /dev/null @@ -1,2970 +0,0 @@ -#ifndef Richards_H -#define Richards_H -#include -#include -#include -#include "CompKernel.h" -#include "ModelFactory.h" -#include "../mprans/ArgumentsDict.h" -#include "xtensor-python/pyarray.hpp" -#define nnz nSpace - -namespace py = pybind11; -#define POWER_SMOOTHNESS_INDICATOR 2 -#define IS_BETAij_ONE 0 -#define GLOBAL_FCT 0 -namespace proteus -{ - // Power entropy // - inline double ENTROPY(const double& phi, const double& phiL, const double& phiR){ - return 1./2.*std::pow(fabs(phi),2.); - } - inline double DENTROPY(const double& phi, const double& phiL, const double& phiR){ - return fabs(phi)*(phi>=0 ? 1 : -1); - } - // Log entropy // for level set from 0 to 1 - inline double ENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ - return std::log(fabs((phi-phiL)*(phiR-phi))+1E-14); - } - inline double DENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ - return (phiL+phiR-2*phi)*((phi-phiL)*(phiR-phi)>=0 ? 1 : -1)/(fabs((phi-phiL)*(phiR-phi))+1E-14); - } -} - -namespace proteus -{ - class Richards_base - { - //The base class defining the interface - public: - virtual ~Richards_base(){} - virtual void calculateResidual(arguments_dict& args)=0; - virtual void calculateJacobian(arguments_dict& args)=0; - virtual void invert(arguments_dict& args)=0; - virtual void FCTStep(arguments_dict& args)=0; - virtual void kth_FCT_step(arguments_dict& args)=0; - virtual void calculateResidual_entropy_viscosity(arguments_dict& args)=0; - virtual void calculateMassMatrix(arguments_dict& args)=0; - }; - - template - class Richards : public Richards_base - { - public: - const int nDOF_test_X_trial_element; - CompKernelType ck; - Richards(): - nDOF_test_X_trial_element(nDOF_test_element*nDOF_trial_element), - ck() - {} - inline - void evaluateCoefficients(const int rowptr[nSpace], - const int colind[nnz], - const double rho, - const double beta, - const double gravity[nSpace], - const double alpha, - const double n_vg, - const double thetaR, - const double thetaSR, - const double KWs[nnz], - const double& u, - double& m, - double& dm, - double f[nSpace], - double df[nSpace], - double a[nnz], - double da[nnz], - double as[nnz], - double& kr, - double& dkr) - { - const int nSpace2 = nSpace * nSpace; - double psiC; - double pcBar; - double pcBar_n; - double pcBar_nM1; - double pcBar_nM2; - double onePlus_pcBar_n; - double sBar; - double sqrt_sBar; - double DsBar_DpsiC; - double thetaW; - double DthetaW_DpsiC; - double vBar; - double vBar2; - double DvBar_DpsiC; - double KWr; - double DKWr_DpsiC; - double rho2 = rho * rho; - double thetaS; - double rhom; - double drhom; - double m_vg; - double pcBarStar; - double sqrt_sBarStar; - - psiC = -u; - m_vg = 1.0 - 1.0 / n_vg; - thetaS = thetaR + thetaSR; - if (psiC > 0.0) - { - pcBar = alpha * psiC; - pcBarStar = pcBar; - if (pcBar < 1.0e-8) - pcBarStar = 1.0e-8; - pcBar_nM2 = pow(pcBarStar, n_vg - 2); - pcBar_nM1 = pcBar_nM2 * pcBar; - pcBar_n = pcBar_nM1 * pcBar; - onePlus_pcBar_n = 1.0 + pcBar_n; - - sBar = pow(onePlus_pcBar_n, -m_vg); - /* using -mn = 1-n */ - DsBar_DpsiC = alpha * (1.0 - n_vg) * (sBar/onePlus_pcBar_n)*pcBar_nM1; - - vBar = 1.0-pcBar_nM1*sBar; - vBar2 = vBar*vBar; - DvBar_DpsiC = -alpha*(n_vg-1.0)*pcBar_nM2*sBar - pcBar_nM1*DsBar_DpsiC; - - thetaW = thetaSR*sBar + thetaR; - DthetaW_DpsiC = thetaSR * DsBar_DpsiC; - - sqrt_sBar = sqrt(sBar); - sqrt_sBarStar = sqrt_sBar; - if (sqrt_sBar < 1.0e-8) - sqrt_sBarStar = 1.0e-8; - KWr= sqrt_sBar*vBar2; - DKWr_DpsiC= ((0.5/sqrt_sBarStar)*DsBar_DpsiC*vBar2 - + - 2.0*sqrt_sBar*vBar*DvBar_DpsiC); - } - else - { - thetaW = thetaS; - DthetaW_DpsiC = 0.0; - KWr = 1.0; - DKWr_DpsiC = 0.0; - } - //slight compressibility - rhom = rho*exp(beta*u); - drhom = beta*rhom; - m = rhom*thetaW; - dm = -rhom*DthetaW_DpsiC+drhom*thetaW; - for (int I=0;I thetaS || thetaW <= thetaR) - { - //cek debug - std::cout<<"rho "< 0.0) - { - isDOFBoundary = 1; - bc_u = bc_u_seepage; - } - else - { - isDOFBoundary = 0; - flux = 0.0; - } - } - /* //set DOF flag and flux correctly if seepage face */ - /* if (isSeepageFace) */ - /* { */ - /* if (flux < 0.0 || u < bc_u_seepage) */ - /* { */ - /* isDOFBoundary = 0; */ - /* flux = 0.0; */ - /* } */ - /* else */ - /* { */ - /* isDOFBoundary = 1; */ - /* bc_u = bc_u_seepage; */ - /* } */ - /* } */ - /* //Dirichlet penalty */ - /* if (isDOFBoundary) */ - /* flux += penalty*(u-bc_u); */ - } - else - flux = bc_flux; - } - - void exteriorNumericalFluxJacobian(const int rowptr[nSpace], - const int colind[nnz], - const int isDOFBoundary, - const double n[nSpace], - const double K[nnz], - const double dK[nnz], - const double grad_psi[nSpace], - const double grad_v[nSpace], - const double dK_rho_g[nSpace], - const double v, - const double penalty, - double& fluxJacobian) - { - if (isDOFBoundary) - { - fluxJacobian = 0.0; - for(int I=0;I& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - double sc_uref = args.scalar("sc_uref"); - double sc_alpha = args.scalar("sc_alpha"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& u_dof_old = args.array("u_dof_old"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m = args.array("q_m"); - xt::pyarray& q_u = args.array("q_u"); - xt::pyarray& q_dV = args.array("q_dV"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - int offset_u = args.scalar("offset_u"); - int stride_u = args.scalar("stride_u"); - xt::pyarray& globalResidual = args.array("globalResidual"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& ebqe_phi = args.array("ebqe_phi"); - double epsFact = args.scalar("epsFact"); - xt::pyarray& ebqe_u = args.array("ebqe_u"); - xt::pyarray& ebqe_flux = args.array("ebqe_flux"); - // PARAMETERS FOR EDGE BASED STABILIZATION - double cE = args.scalar("cE"); - double cK = args.scalar("cK"); - // PARAMETERS FOR LOG BASED ENTROPY FUNCTION - double uL = args.scalar("uL"); - double uR = args.scalar("uR"); - // PARAMETERS FOR EDGE VISCOSITY - int numDOFs = args.scalar("numDOFs"); - int NNZ = args.scalar("NNZ"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); - xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); - xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); - xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); - // C matrices - xt::pyarray& Cx = args.array("Cx"); - xt::pyarray& Cy = args.array("Cy"); - xt::pyarray& Cz = args.array("Cz"); - xt::pyarray& CTx = args.array("CTx"); - xt::pyarray& CTy = args.array("CTy"); - xt::pyarray& CTz = args.array("CTz"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); - int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); - // FOR FCT - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& fluxMatrix = args.array("fluxMatrix"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); - xt::pyarray& min_s_bc = args.array("min_s_bc"); - xt::pyarray& max_s_bc = args.array("max_s_bc"); - // AUX QUANTITIES OF INTEREST - xt::pyarray& quantDOFs = args.array("quantDOFs"); - xt::pyarray& sLow = args.array("sLow"); - xt::pyarray& sn = args.array("sn"); - - assert(a_rowptr.data()[nSpace] == nnz); - assert(a_rowptr.data()[nSpace] == nSpace); - //cek should this be read in? - double Ct_sge = 4.0; - - //loop over elements to compute volume integrals and load them into element and global residual - // - //eN is the element index - //eN_k is the quadrature point index for a scalar - //eN_k_nSpace is the quadrature point index for a vector - //eN_i is the element test function index - //eN_j is the element trial function index - //eN_k_j is the quadrature point index for a trial function - //eN_k_i is the quadrature point index for a trial function - for(int eN=0;eN& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); - xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); - xt::pyarray& globalJacobian = args.array("globalJacobian"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - assert(a_rowptr.data()[nSpace] == nnz); - assert(a_rowptr.data()[nSpace] == nSpace); - double Ct_sge = 4.0; - - // - //loop over elements to compute volume integrals and load them into the element Jacobians and global Jacobian - // - for(int eN=0;eN& bc_mask = args.array("bc_mask"); - int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern - int numDOFs = args.scalar("numDOFs"); //number of DOFs - double dt = args.scalar("dt"); - xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) - xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn - xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn - xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& limited_solution = args.array("limited_solution"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets - xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices - xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 - xt::pyarray& max_s_bc = args.array("max_s_bc"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int MONOLITHIC = args.scalar("MONOLITHIC"); - register double Rpos[numDOFs], Rneg[numDOFs]; - register double FluxCorrectionMatrix[NNZ]; - register double solL[numDOFs]; - register double sdot[numDOFs]; - ////////////////// - // LOOP in DOFs // - ////////////////// - int ij=0; - for (int i=0; i 0) ? 1. : 0.); - Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); - - //update ij - ij+=1; - //std::cout<<"sdoti error"<0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])) - * FluxCorrectionMatrix[ij]; - alpha_dot = fmin(1.0, beta_ij*fabs(alpha_fA)/MassMatrix.data()[ij]/fmax(1.0e-8,fabs(sdoti-sdotj))); - if (MONOLITHIC == 0) - { - ith_Limiter_times_FluxCorrectionMatrix += alpha_fA; - } - else - { - ith_Limiter_times_FluxCorrectionMatrix += alpha_fA + (LUMPED_MASS_MATRIX == 1 ? 0. : 1.)*dt*alpha_dot*MassMatrix.data()[ij]*(sdoti-sdotj); - } - //update ij - ij+=1; - } - limited_solution.data()[i] = solL[i] + 1./lumped_mass_matrix.data()[i]*ith_Limiter_times_FluxCorrectionMatrix*bc_mask[i]; - } - } - - void kth_FCT_step(arguments_dict& args) - { - int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern - int numDOFs = args.scalar("numDOFs"); //number of DOFs - int num_fct_iter = args.scalar("num_fct_iter"); - double dt = args.scalar("dt"); - xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) - xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn - xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn - xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& solLim = args.array("limited_solution"); - xt::pyarray& MC = args.array("MC"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& FluxMatrix = args.array("FluxMatrix"); - xt::pyarray& limitedFlux = args.array("limited_Flux"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets - xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices - xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 - xt::pyarray& max_s_bc = args.array("max_s_bc"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int MONOLITHIC = args.scalar("MONOLITHIC"); - register double Rpos[numDOFs], Rneg[numDOFs]; - int ij=0; - - ////////////////////////////////////////////////////// - // ********** COMPUTE LOW ORDER SOLUTION ********** // - ////////////////////////////////////////////////////// - if (num_fct_iter == 0) - { // No FCT for global bounds - for (int i=0; i 0) ? 1. : 0.); - // update ij - ij+=1; - } - // compute Q vectors - double mi = ML.data()[i]; - double solLimi = solLim.data()[i]; - double Qposi = mi*(maxi-solLimi); - // compute R vectors - Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - } - ij=0; - for (int i=0; i0 ? Rposi : Rpos[j]); - // compute limited flux - ith_Limiter_times_FluxCorrectionMatrix += Lij*Fluxij; - - // update limited flux - limitedFlux.data()[ij] = Lij*Fluxij; - - //update FluxMatrix - FluxMatrix.data()[ij] = Fluxij; - - //update ij - ij+=1; - } - //update limited solution - double mi = ML.data()[i]; - solLim.data()[i] += 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; - } - } - } - - // ***************************************** // - // ********** HIGH ORDER SOLUTION ********** // - // ***************************************** // - ij=0; - for (int i=0; i 0 ? 1. : 0.); - Pnegi += fij * (fij < 0 ? 1. : 0.); - //update ij - ij+=1; - } - // compute Q vectors // - double mi = ML.data()[i]; - double Qposi = mi*(maxi-solLim.data()[i]); - double Qnegi = mi*(mini-solLim.data()[i]); - // compute R vectors // - Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); - } - - // COMPUTE LIMITERS // - ij=0; - for (int i=0; i 0 ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j]); - // compute ith_limited_flux_correction - ith_limited_flux_correction += Lij*fij; - ij+=1; - } - double mi = ML.data()[i]; - solLim[i] += 1./mi*ith_limited_flux_correction; - } - } - - void calculateResidual_entropy_viscosity(arguments_dict& args) - { - xt::pyarray& globalJacobian = args.array("globalJacobian"); - double Theta = args.scalar("Theta"); - xt::pyarray& bc_mask = args.array("bc_mask"); - double dt = args.scalar("dt"); - xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - double sc_uref = args.scalar("sc_uref"); - double sc_alpha = args.scalar("sc_alpha"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& r_l2g = args.array("r_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - int degree_polynomial = args.scalar("degree_polynomial"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& u_dof_old = args.array("u_dof_old"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m = args.array("q_m"); - xt::pyarray& q_u = args.array("q_u"); - xt::pyarray& q_dV = args.array("q_dV"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - int offset_u = args.scalar("offset_u"); - int stride_u = args.scalar("stride_u"); - xt::pyarray& globalResidual = args.array("globalResidual"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& ebqe_phi = args.array("ebqe_phi"); - double epsFact = args.scalar("epsFact"); - xt::pyarray& ebqe_u = args.array("ebqe_u"); - xt::pyarray& ebqe_flux = args.array("ebqe_flux"); - // PARAMETERS FOR EDGE BASED STABILIZATION - double cE = args.scalar("cE"); - double cK = args.scalar("cK"); - // PARAMETERS FOR LOG BASED ENTROPY FUNCTION - double uL = args.scalar("uL"); - double uR = args.scalar("uR"); - // PARAMETERS FOR EDGE VISCOSITY - int numDOFs = args.scalar("numDOFs"); - int NNZ = args.scalar("NNZ"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); - xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); - xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); - xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); - // C matrices - xt::pyarray& Cx = args.array("Cx"); - xt::pyarray& Cy = args.array("Cy"); - xt::pyarray& Cz = args.array("Cz"); - xt::pyarray& CTx = args.array("CTx"); - xt::pyarray& CTy = args.array("CTy"); - xt::pyarray& CTz = args.array("CTz"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); - int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); - // FOR FCT - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& fluxMatrix = args.array("fluxMatrix"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); - xt::pyarray& min_s_bc = args.array("min_s_bc"); - xt::pyarray& max_s_bc = args.array("max_s_bc"); - // AUX QUANTITIES OF INTEREST - xt::pyarray& quantDOFs = args.array("quantDOFs"); - xt::pyarray& sLow = args.array("sLow"); - xt::pyarray& sn = args.array("sn"); - register double Rpos[numDOFs], Rneg[numDOFs]; - //register double FluxCorrectionMatrix[NNZ]; - // NOTE: This function follows a different (but equivalent) implementation of the smoothness based indicator than NCLS.h - // Allocate space for the transport matrices - // This is used for first order KUZMIN'S METHOD - register double TransportMatrix[NNZ],TransportMatrixConsistent[NNZ]; - register double TransportMatrixn[NNZ],TransportMatrixConsistentn[NNZ]; - std::valarray u_free_dof(numDOFs); - std::valarray u_free_dof_old(numDOFs); - std::valarray ML2(numDOFs); - for(int eN=0;eN= 0 && isFluxBoundary_u[ebNE_kb] != 1 ) //outflow. This is handled via the transport matrices. Then flux_ext=0 and dflux_ext!=0 */ - /* { */ - /* dflux_ext = flow; */ - /* flux_ext = 0; */ - /* // save external u */ - /* ebqe_u[ebNE_kb] = u_ext; */ - /* } */ - /* else // inflow. This is handled via the boundary integral. Then flux_ext!=0 and dflux_ext=0 */ - /* { */ - /* dflux_ext = 0; */ - /* // save external u */ - /* ebqe_u[ebNE_kb] = isDOFBoundary_u[ebNE_kb]*ebqe_bc_u_ext[ebNE_kb]+(1-isDOFBoundary_u[ebNE_kb])*u_ext; */ - /* if (isDOFBoundary_u[ebNE_kb] == 1) */ - /* flux_ext = ebqe_bc_u_ext[ebNE_kb]*flow; */ - /* else if (isFluxBoundary_u[ebNE_kb] == 1) */ - /* flux_ext = ebqe_bc_flux_u_ext[ebNE_kb]; */ - /* else */ - /* { */ - /* std::cout<<"warning: VOF open boundary with no external trace, setting to zero for inflow"<= 0.) - { - alpha_numerator_pos += alpha_num; - alpha_denominator_pos += alpha_num; - } - else - { - alpha_numerator_neg += alpha_num; - alpha_denominator_neg += fabs(alpha_num); - } - //update ij - ij+=1; - } - // scale g vector by lumped mass matrix - if (fabs(ML.data()[i] - ML2[i]) > 1.0e-16) - std::cout<<"ML "< 0.0) - // assert( (xi[I] - xj[I]) == delta_x_ij[offset*3+I]); - //gi_times_x += gi[I]*(xi[I]-xj[I]); - gi_times_x += gi[I]*delta_x_ij.data()[offset*3+I]; - } - // compute the positive and negative part of gi*(xi-xj) - SumPos += gi_times_x > 0 ? gi_times_x : 0; - SumNeg += gi_times_x < 0 ? gi_times_x : 0; - } - double sigmaPosi = fmin(1.,(fabs(SumNeg)+1E-15)/(SumPos+1E-15)); - double sigmaNegi = fmin(1.,(SumPos+1E-15)/(fabs(SumNeg)+1E-15)); - double alpha_numi = fabs(sigmaPosi*alpha_numerator_pos + sigmaNegi*alpha_numerator_neg); - double alpha_deni = sigmaPosi*alpha_denominator_pos + sigmaNegi*alpha_denominator_neg; - if (IS_BETAij_ONE == 1) - { - alpha_numi = fabs(alpha_numerator_pos + alpha_numerator_neg); - alpha_deni = alpha_denominator_pos + alpha_denominator_neg; - } - double alphai = alpha_numi/(alpha_deni+1E-15); - quantDOFs.data()[i] = alphai; - - if (POWER_SMOOTHNESS_INDICATOR==0) - psi[i] = 1.0; - else - psi[i] = std::pow(alphai,POWER_SMOOTHNESS_INDICATOR); //NOTE: they use alpha^2 in the paper - } - ///////////////////////////////////////////// - // ** LOOP IN DOFs FOR EDGE BASED TERMS ** // - ///////////////////////////////////////////// - ij=0; - for (int i=0; i Dissipation matrices as well. - double soli = u_free_dof[i]; // solution at time tn for the ith DOF - double solni = u_free_dof_old[i]; // solution at time tn for the ith DOF - for (int I=0;I mMax) - { - std::cout<<"mass out of bounds "< 0) ? 1. : 0.); - // Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); - // ij+=1; - // } - // double mi = ML[i]; - // double solni = u_dof_old[i]; - // double Qposi = mi*(maxi-solni); - // double Qnegi = mi*(mini-solni); - - //std::cout << Qposi << std::endl; - // Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - // Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); - - //if (Rpos[i] < 0) - //{ - // std::cout << mi << "\t" << maxi << "\t" << solni << std::endl; - // std::cout << Qposi << "\t" << Pposi << std::endl; - // std::cout << Rpos[i] << std::endl; - //abort(); - //} - //} - - //ij=0; - //for (int i=0; i 1.0 || Rposi < 0.0) - //std::cout << "Rposi: " << Rposi << std::endl; - //if (Rnegi > 1.0 || Rnegi < 0.0) - //std::cout << "Rnegi: " << Rnegi << std::endl; - - // LOOP OVER THE SPARSITY PATTERN (j-LOOP)// - // for (int offset=csrRowIndeces_DofLoops.data()[i]; - // offset0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])); - // //Lij=0.0; - // ith_Limiter_times_FluxCorrectionMatrix += Lij*FluxCorrectionMatrix[ij]; - // //update ij - // ij+=1; - // } - // double mi = ML[i]; - // double solni = u_dof_old[i]; - // globalResidual[i] = solni + 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; - //} - - } - - void invert(arguments_dict& args) - { - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - xt::pyarray& globalResidual = args.array("globalResidual"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - int numDOFs = args.scalar("numDOFs"); - for (int i=0; i mMax) - { - std::cout<<"mass out of bounds "<("dt"); - xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - //element boundary - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - //physics - int nElements_global = args.scalar("nElements_global"); - //new - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - //end new - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& r_l2g = args.array("r_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - int degree_polynomial = args.scalar("degree_polynomial"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); - xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); - xt::pyarray& globalJacobian = args.array("globalJacobian"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - //std::cout<<"ndjaco address "<(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - else if (nSpaceIn == 2) - return proteus::chooseAndAllocateDiscretization2D(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - else - { - assert(nSpaceIn == 3); - return proteus::chooseAndAllocateDiscretization(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - } - } -}//proteus -#endif diff --git a/richards_fct/richards/edit/Richards.h:Zone.Identifier b/richards_fct/richards/edit/Richards.h:Zone.Identifier deleted file mode 100644 index 1bf0b28e7b..0000000000 --- a/richards_fct/richards/edit/Richards.h:Zone.Identifier +++ /dev/null @@ -1,3 +0,0 @@ -[ZoneTransfer] -ZoneId=3 -HostUrl=https://github.com/ diff --git a/richards_fct/richards/edit/Richards.py:Zone.Identifier b/richards_fct/richards/edit/Richards.py:Zone.Identifier deleted file mode 100644 index 1bf0b28e7b..0000000000 --- a/richards_fct/richards/edit/Richards.py:Zone.Identifier +++ /dev/null @@ -1,3 +0,0 @@ -[ZoneTransfer] -ZoneId=3 -HostUrl=https://github.com/ diff --git a/richards_fct/richards/edit/Richards_abc.h b/richards_fct/richards/edit/Richards_abc.h deleted file mode 100644 index c871014017..0000000000 --- a/richards_fct/richards/edit/Richards_abc.h +++ /dev/null @@ -1,2967 +0,0 @@ - -#ifndef Richards_H -#define Richards_H -#include -#include -#include -#include "CompKernel.h" -#include "ModelFactory.h" -#include "../mprans/ArgumentsDict.h" -#include "xtensor-python/pyarray.hpp" -#define nnz nSpace - -namespace py = pybind11; -#define POWER_SMOOTHNESS_INDICATOR 2 -#define IS_BETAij_ONE 0 -#define GLOBAL_FCT 0 -namespace proteus -{ - // Power entropy // - inline double ENTROPY(const double& phi, const double& phiL, const double& phiR){ - return 1./2.*std::pow(fabs(phi),2.); - } - inline double DENTROPY(const double& phi, const double& phiL, const double& phiR){ - return fabs(phi)*(phi>=0 ? 1 : -1); - } - // Log entropy // for level set from 0 to 1 - inline double ENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ - return std::log(fabs((phi-phiL)*(phiR-phi))+1E-14); - } - inline double DENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ - return (phiL+phiR-2*phi)*((phi-phiL)*(phiR-phi)>=0 ? 1 : -1)/(fabs((phi-phiL)*(phiR-phi))+1E-14); - } -} - -namespace proteus -{ - class Richards_base - { - //The base class defining the interface - public: - virtual ~Richards_base(){} - virtual void calculateResidual(arguments_dict& args)=0; - virtual void calculateJacobian(arguments_dict& args)=0; - virtual void invert(arguments_dict& args)=0; - virtual void FCTStep(arguments_dict& args)=0; - virtual void kth_FCT_step(arguments_dict& args)=0; - virtual void calculateResidual_entropy_viscosity(arguments_dict& args)=0; - virtual void calculateMassMatrix(arguments_dict& args)=0; - }; - - template - class Richards : public Richards_base - { - public: - const int nDOF_test_X_trial_element; - CompKernelType ck; - Richards(): - nDOF_test_X_trial_element(nDOF_test_element*nDOF_trial_element), - ck() - {} - inline - void evaluateCoefficients(const int rowptr[nSpace], - const int colind[nnz], - const double rho, - const double beta, - const double gravity[nSpace], - const double alpha, - const double n_vg, - const double thetaR, - const double thetaSR, - const double KWs[nnz], - const double& u, - double& m, - double& dm, - double f[nSpace], - double df[nSpace], - double a[nnz], - double da[nnz], - double as[nnz], - double& kr, - double& dkr) - { - const int nSpace2 = nSpace * nSpace; - double psiC; - double pcBar; - double pcBar_n; - double pcBar_nM1; - double pcBar_nM2; - double onePlus_pcBar_n; - double sBar; - double sqrt_sBar; - double DsBar_DpsiC; - double thetaW; - double DthetaW_DpsiC; - double vBar; - double vBar2; - double DvBar_DpsiC; - double KWr; - double DKWr_DpsiC; - double rho2 = rho * rho; - double thetaS; - double rhom; - double drhom; - double m_vg; - double pcBarStar; - double sqrt_sBarStar; - - psiC = -u; - m_vg = 1.0 - 1.0 / n_vg; - thetaS = thetaR + thetaSR; - if (psiC > 0.0) - { - pcBar = alpha * psiC; - pcBarStar = pcBar; - if (pcBar < 1.0e-8) - pcBarStar = 1.0e-8; - pcBar_nM2 = pow(pcBarStar, n_vg - 2); - pcBar_nM1 = pcBar_nM2 * pcBar; - pcBar_n = pcBar_nM1 * pcBar; - onePlus_pcBar_n = 1.0 + pcBar_n; - - sBar = pow(onePlus_pcBar_n, -m_vg); - /* using -mn = 1-n */ - DsBar_DpsiC = alpha * (1.0 - n_vg) * (sBar/onePlus_pcBar_n)*pcBar_nM1; - - vBar = 1.0-pcBar_nM1*sBar; - vBar2 = vBar*vBar; - DvBar_DpsiC = -alpha*(n_vg-1.0)*pcBar_nM2*sBar - pcBar_nM1*DsBar_DpsiC; - - thetaW = thetaSR*sBar + thetaR; - DthetaW_DpsiC = thetaSR * DsBar_DpsiC; - - sqrt_sBar = sqrt(sBar); - sqrt_sBarStar = sqrt_sBar; - if (sqrt_sBar < 1.0e-8) - sqrt_sBarStar = 1.0e-8; - KWr= sqrt_sBar*vBar2; - DKWr_DpsiC= ((0.5/sqrt_sBarStar)*DsBar_DpsiC*vBar2 - + - 2.0*sqrt_sBar*vBar*DvBar_DpsiC); - } - else - { - thetaW = thetaS; - DthetaW_DpsiC = 0.0; - KWr = 1.0; - DKWr_DpsiC = 0.0; - } - //slight compressibility - rhom = rho*exp(beta*u); - drhom = beta*rhom; - m = rhom*thetaW; - dm = -rhom*DthetaW_DpsiC+drhom*thetaW; - for (int I=0;I thetaS || thetaW <= thetaR) - { - //cek debug - std::cout<<"rho "< 0.0) - { - isDOFBoundary = 1; - bc_u = bc_u_seepage; - } - else - { - isDOFBoundary = 0; - flux = 0.0; - } - } - /* //set DOF flag and flux correctly if seepage face */ - /* if (isSeepageFace) */ - /* { */ - /* if (flux < 0.0 || u < bc_u_seepage) */ - /* { */ - /* isDOFBoundary = 0; */ - /* flux = 0.0; */ - /* } */ - /* else */ - /* { */ - /* isDOFBoundary = 1; */ - /* bc_u = bc_u_seepage; */ - /* } */ - /* } */ - /* //Dirichlet penalty */ - /* if (isDOFBoundary) */ - /* flux += penalty*(u-bc_u); */ - } - else - flux = bc_flux; - } - - void exteriorNumericalFluxJacobian(const int rowptr[nSpace], - const int colind[nnz], - const int isDOFBoundary, - const double n[nSpace], - const double K[nnz], - const double dK[nnz], - const double grad_psi[nSpace], - const double grad_v[nSpace], - const double dK_rho_g[nSpace], - const double v, - const double penalty, - double& fluxJacobian) - { - if (isDOFBoundary) - { - fluxJacobian = 0.0; - for(int I=0;I& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - double sc_uref = args.scalar("sc_uref"); - double sc_alpha = args.scalar("sc_alpha"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& u_dof_old = args.array("u_dof_old"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m = args.array("q_m"); - xt::pyarray& q_u = args.array("q_u"); - xt::pyarray& q_dV = args.array("q_dV"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - int offset_u = args.scalar("offset_u"); - int stride_u = args.scalar("stride_u"); - xt::pyarray& globalResidual = args.array("globalResidual"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& ebqe_phi = args.array("ebqe_phi"); - double epsFact = args.scalar("epsFact"); - xt::pyarray& ebqe_u = args.array("ebqe_u"); - xt::pyarray& ebqe_flux = args.array("ebqe_flux"); - // PARAMETERS FOR EDGE BASED STABILIZATION - double cE = args.scalar("cE"); - double cK = args.scalar("cK"); - // PARAMETERS FOR LOG BASED ENTROPY FUNCTION - double uL = args.scalar("uL"); - double uR = args.scalar("uR"); - // PARAMETERS FOR EDGE VISCOSITY - int numDOFs = args.scalar("numDOFs"); - int NNZ = args.scalar("NNZ"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); - xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); - xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); - xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); - // C matrices - xt::pyarray& Cx = args.array("Cx"); - xt::pyarray& Cy = args.array("Cy"); - xt::pyarray& Cz = args.array("Cz"); - xt::pyarray& CTx = args.array("CTx"); - xt::pyarray& CTy = args.array("CTy"); - xt::pyarray& CTz = args.array("CTz"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); - int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); - // FOR FCT - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& fluxMatrix = args.array("fluxMatrix"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); - xt::pyarray& min_s_bc = args.array("min_s_bc"); - xt::pyarray& max_s_bc = args.array("max_s_bc"); - // AUX QUANTITIES OF INTEREST - xt::pyarray& quantDOFs = args.array("quantDOFs"); - xt::pyarray& sLow = args.array("sLow"); - xt::pyarray& sn = args.array("sn"); - - assert(a_rowptr.data()[nSpace] == nnz); - assert(a_rowptr.data()[nSpace] == nSpace); - //cek should this be read in? - double Ct_sge = 4.0; - - //loop over elements to compute volume integrals and load them into element and global residual - // - //eN is the element index - //eN_k is the quadrature point index for a scalar - //eN_k_nSpace is the quadrature point index for a vector - //eN_i is the element test function index - //eN_j is the element trial function index - //eN_k_j is the quadrature point index for a trial function - //eN_k_i is the quadrature point index for a trial function - for(int eN=0;eN& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); - xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); - xt::pyarray& globalJacobian = args.array("globalJacobian"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - assert(a_rowptr.data()[nSpace] == nnz); - assert(a_rowptr.data()[nSpace] == nSpace); - double Ct_sge = 4.0; - - // - //loop over elements to compute volume integrals and load them into the element Jacobians and global Jacobian - // - for(int eN=0;eN& bc_mask = args.array("bc_mask"); - int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern - int numDOFs = args.scalar("numDOFs"); //number of DOFs - double dt = args.scalar("dt"); - xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) - xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn - xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn - xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& limited_solution = args.array("limited_solution"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets - xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices - xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 - xt::pyarray& max_s_bc = args.array("max_s_bc"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int MONOLITHIC = args.scalar("MONOLITHIC"); - register double Rpos[numDOFs], Rneg[numDOFs]; - register double FluxCorrectionMatrix[NNZ]; - register double solL[numDOFs]; - register double sdot[numDOFs]; - ////////////////// - // LOOP in DOFs // - ////////////////// - int ij=0; - for (int i=0; i 0) ? 1. : 0.); - Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); - - //update ij - ij+=1; - //std::cout<<"sdoti error"<0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])) - * FluxCorrectionMatrix[ij]; - alpha_dot = fmin(1.0, beta_ij*fabs(alpha_fA)/MassMatrix.data()[ij]/fmax(1.0e-8,fabs(sdoti-sdotj))); - if (MONOLITHIC == 0) - { - ith_Limiter_times_FluxCorrectionMatrix += alpha_fA; - } - else - { - ith_Limiter_times_FluxCorrectionMatrix += alpha_fA + (LUMPED_MASS_MATRIX == 1 ? 0. : 1.)*dt*alpha_dot*MassMatrix.data()[ij]*(sdoti-sdotj); - } - //update ij - ij+=1; - } - limited_solution.data()[i] = solL[i] + 1./lumped_mass_matrix.data()[i]*ith_Limiter_times_FluxCorrectionMatrix*bc_mask[i]; - } - } - - void kth_FCT_step(arguments_dict& args) - { - int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern - int numDOFs = args.scalar("numDOFs"); //number of DOFs - int num_fct_iter = args.scalar("num_fct_iter"); - double dt = args.scalar("dt"); - xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) - xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn - xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn - xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& solLim = args.array("limited_solution"); - xt::pyarray& MC = args.array("MC"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& FluxMatrix = args.array("FluxMatrix"); - xt::pyarray& limitedFlux = args.array("limited_Flux"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets - xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices - xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 - xt::pyarray& max_s_bc = args.array("max_s_bc"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int MONOLITHIC = args.scalar("MONOLITHIC"); - register double Rpos[numDOFs], Rneg[numDOFs]; - int ij=0; - - ////////////////////////////////////////////////////// - // ********** COMPUTE LOW ORDER SOLUTION ********** // - ////////////////////////////////////////////////////// - if (num_fct_iter == 0) - { // No FCT for global bounds - for (int i=0; i 0) ? 1. : 0.); - // update ij - ij+=1; - } - // compute Q vectors - double mi = ML.data()[i]; - double solLimi = solLim.data()[i]; - double Qposi = mi*(maxi-solLimi); - // compute R vectors - Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - } - ij=0; - for (int i=0; i0 ? Rposi : Rpos[j]); - // compute limited flux - ith_Limiter_times_FluxCorrectionMatrix += Lij*Fluxij; - - // update limited flux - limitedFlux.data()[ij] = Lij*Fluxij; - - //update FluxMatrix - FluxMatrix.data()[ij] = Fluxij; - - //update ij - ij+=1; - } - //update limited solution - double mi = ML.data()[i]; - solLim.data()[i] += 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; - } - } - } - - // ***************************************** // - // ********** HIGH ORDER SOLUTION ********** // - // ***************************************** // - ij=0; - for (int i=0; i 0 ? 1. : 0.); - Pnegi += fij * (fij < 0 ? 1. : 0.); - //update ij - ij+=1; - } - // compute Q vectors // - double mi = ML.data()[i]; - double Qposi = mi*(maxi-solLim.data()[i]); - double Qnegi = mi*(mini-solLim.data()[i]); - // compute R vectors // - Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); - } - - // COMPUTE LIMITERS // - ij=0; - for (int i=0; i 0 ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j]); - // compute ith_limited_flux_correction - ith_limited_flux_correction += Lij*fij; - ij+=1; - } - double mi = ML.data()[i]; - solLim[i] += 1./mi*ith_limited_flux_correction; - } - } - - void calculateResidual_entropy_viscosity(arguments_dict& args) - { - xt::pyarray& globalJacobian = args.array("globalJacobian"); - double Theta = args.scalar("Theta"); - xt::pyarray& bc_mask = args.array("bc_mask"); - double dt = args.scalar("dt"); - xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - double sc_uref = args.scalar("sc_uref"); - double sc_alpha = args.scalar("sc_alpha"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& r_l2g = args.array("r_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - int degree_polynomial = args.scalar("degree_polynomial"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& u_dof_old = args.array("u_dof_old"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m = args.array("q_m"); - xt::pyarray& q_u = args.array("q_u"); - xt::pyarray& q_dV = args.array("q_dV"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - int offset_u = args.scalar("offset_u"); - int stride_u = args.scalar("stride_u"); - xt::pyarray& globalResidual = args.array("globalResidual"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& ebqe_phi = args.array("ebqe_phi"); - double epsFact = args.scalar("epsFact"); - xt::pyarray& ebqe_u = args.array("ebqe_u"); - xt::pyarray& ebqe_flux = args.array("ebqe_flux"); - // PARAMETERS FOR EDGE BASED STABILIZATION - double cE = args.scalar("cE"); - double cK = args.scalar("cK"); - // PARAMETERS FOR LOG BASED ENTROPY FUNCTION - double uL = args.scalar("uL"); - double uR = args.scalar("uR"); - // PARAMETERS FOR EDGE VISCOSITY - int numDOFs = args.scalar("numDOFs"); - int NNZ = args.scalar("NNZ"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); - xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); - xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); - xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); - // C matrices - xt::pyarray& Cx = args.array("Cx"); - xt::pyarray& Cy = args.array("Cy"); - xt::pyarray& Cz = args.array("Cz"); - xt::pyarray& CTx = args.array("CTx"); - xt::pyarray& CTy = args.array("CTy"); - xt::pyarray& CTz = args.array("CTz"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); - int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); - // FOR FCT - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& fluxMatrix = args.array("fluxMatrix"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); - xt::pyarray& min_s_bc = args.array("min_s_bc"); - xt::pyarray& max_s_bc = args.array("max_s_bc"); - // AUX QUANTITIES OF INTEREST - xt::pyarray& quantDOFs = args.array("quantDOFs"); - xt::pyarray& sLow = args.array("sLow"); - xt::pyarray& sn = args.array("sn"); - register double Rpos[numDOFs], Rneg[numDOFs]; - //register double FluxCorrectionMatrix[NNZ]; - // NOTE: This function follows a different (but equivalent) implementation of the smoothness based indicator than NCLS.h - // Allocate space for the transport matrices - // This is used for first order KUZMIN'S METHOD - register double TransportMatrix[NNZ],TransportMatrixConsistent[NNZ]; - register double TransportMatrixn[NNZ],TransportMatrixConsistentn[NNZ]; - std::valarray u_free_dof(numDOFs); - std::valarray u_free_dof_old(numDOFs); - std::valarray ML2(numDOFs); - for(int eN=0;eN= 0 && isFluxBoundary_u[ebNE_kb] != 1 ) //outflow. This is handled via the transport matrices. Then flux_ext=0 and dflux_ext!=0 */ - /* { */ - /* dflux_ext = flow; */ - /* flux_ext = 0; */ - /* // save external u */ - /* ebqe_u[ebNE_kb] = u_ext; */ - /* } */ - /* else // inflow. This is handled via the boundary integral. Then flux_ext!=0 and dflux_ext=0 */ - /* { */ - /* dflux_ext = 0; */ - /* // save external u */ - /* ebqe_u[ebNE_kb] = isDOFBoundary_u[ebNE_kb]*ebqe_bc_u_ext[ebNE_kb]+(1-isDOFBoundary_u[ebNE_kb])*u_ext; */ - /* if (isDOFBoundary_u[ebNE_kb] == 1) */ - /* flux_ext = ebqe_bc_u_ext[ebNE_kb]*flow; */ - /* else if (isFluxBoundary_u[ebNE_kb] == 1) */ - /* flux_ext = ebqe_bc_flux_u_ext[ebNE_kb]; */ - /* else */ - /* { */ - /* std::cout<<"warning: VOF open boundary with no external trace, setting to zero for inflow"<= 0.) - { - alpha_numerator_pos += alpha_num; - alpha_denominator_pos += alpha_num; - } - else - { - alpha_numerator_neg += alpha_num; - alpha_denominator_neg += fabs(alpha_num); - } - //update ij - ij+=1; - } - // scale g vector by lumped mass matrix - if (fabs(ML.data()[i] - ML2[i]) > 1.0e-16) - std::cout<<"ML "< 0.0) - // assert( (xi[I] - xj[I]) == delta_x_ij[offset*3+I]); - //gi_times_x += gi[I]*(xi[I]-xj[I]); - gi_times_x += gi[I]*delta_x_ij.data()[offset*3+I]; - } - // compute the positive and negative part of gi*(xi-xj) - SumPos += gi_times_x > 0 ? gi_times_x : 0; - SumNeg += gi_times_x < 0 ? gi_times_x : 0; - } - double sigmaPosi = fmin(1.,(fabs(SumNeg)+1E-15)/(SumPos+1E-15)); - double sigmaNegi = fmin(1.,(SumPos+1E-15)/(fabs(SumNeg)+1E-15)); - double alpha_numi = fabs(sigmaPosi*alpha_numerator_pos + sigmaNegi*alpha_numerator_neg); - double alpha_deni = sigmaPosi*alpha_denominator_pos + sigmaNegi*alpha_denominator_neg; - if (IS_BETAij_ONE == 1) - { - alpha_numi = fabs(alpha_numerator_pos + alpha_numerator_neg); - alpha_deni = alpha_denominator_pos + alpha_denominator_neg; - } - double alphai = alpha_numi/(alpha_deni+1E-15); - quantDOFs.data()[i] = alphai; - - if (POWER_SMOOTHNESS_INDICATOR==0) - psi[i] = 1.0; - else - psi[i] = std::pow(alphai,POWER_SMOOTHNESS_INDICATOR); //NOTE: they use alpha^2 in the paper - } - ///////////////////////////////////////////// - // ** LOOP IN DOFs FOR EDGE BASED TERMS ** // - ///////////////////////////////////////////// - ij=0; - for (int i=0; i Dissipation matrices as well. - double soli = u_free_dof[i]; // solution at time tn for the ith DOF - double solni = u_free_dof_old[i]; // solution at time tn for the ith DOF - for (int I=0;I mMax) - { - std::cout<<"mass out of bounds "< 0) ? 1. : 0.); - // Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); - // ij+=1; - // } - // double mi = ML[i]; - // double solni = u_dof_old[i]; - // double Qposi = mi*(maxi-solni); - // double Qnegi = mi*(mini-solni); - - //std::cout << Qposi << std::endl; - // Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - // Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); - - //if (Rpos[i] < 0) - //{ - // std::cout << mi << "\t" << maxi << "\t" << solni << std::endl; - // std::cout << Qposi << "\t" << Pposi << std::endl; - // std::cout << Rpos[i] << std::endl; - //abort(); - //} - //} - - //ij=0; - //for (int i=0; i 1.0 || Rposi < 0.0) - //std::cout << "Rposi: " << Rposi << std::endl; - //if (Rnegi > 1.0 || Rnegi < 0.0) - //std::cout << "Rnegi: " << Rnegi << std::endl; - - // LOOP OVER THE SPARSITY PATTERN (j-LOOP)// - // for (int offset=csrRowIndeces_DofLoops.data()[i]; - // offset0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])); - // //Lij=0.0; - // ith_Limiter_times_FluxCorrectionMatrix += Lij*FluxCorrectionMatrix[ij]; - // //update ij - // ij+=1; - // } - // double mi = ML[i]; - // double solni = u_dof_old[i]; - // globalResidual[i] = solni + 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; - //} - - } - - void invert(arguments_dict& args) - { - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - xt::pyarray& globalResidual = args.array("globalResidual"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - int numDOFs = args.scalar("numDOFs"); - for (int i=0; i mMax) - { - std::cout<<"mass out of bounds "<("dt"); - xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - //element boundary - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - //physics - int nElements_global = args.scalar("nElements_global"); - //new - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - //end new - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& r_l2g = args.array("r_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - int degree_polynomial = args.scalar("degree_polynomial"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); - xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); - xt::pyarray& globalJacobian = args.array("globalJacobian"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - //std::cout<<"ndjaco address "<(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - else if (nSpaceIn == 2) - return proteus::chooseAndAllocateDiscretization2D(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - else - { - assert(nSpaceIn == 3); - return proteus::chooseAndAllocateDiscretization(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - } - } -}//proteus -#endif diff --git a/richards_fct/richards/edit/Richards_abc.py b/richards_fct/richards/edit/Richards_abc.py deleted file mode 100644 index abc00527bf..0000000000 --- a/richards_fct/richards/edit/Richards_abc.py +++ /dev/null @@ -1,1745 +0,0 @@ -from __future__ import division -from builtins import range -from past.utils import old_div -import proteus -from .cRichards import * -import numpy as np -from proteus.Transport import OneLevelTransport -from proteus.Transport import TC_base, NonlinearEquation, logEvent, memory -from proteus.Transport import FluxBoundaryConditions, Comm, cfemIntegrals -from proteus.Transport import DOFBoundaryConditions, Quadrature -from proteus.mprans import cArgumentsDict -from proteus.LinearAlgebraTools import SparseMat -from proteus import TimeIntegration -from proteus.NonlinearSolvers import ExplicitLumpedMassMatrixForRichards - -class ThetaScheme(TimeIntegration.BackwardEuler): - def __init__(self,transport,integrateInterpolationPoints=False): - self.transport=transport - TimeIntegration.BackwardEuler.__init__(self,transport, integrateInterpolationPoints) - def updateTimeHistory(self,resetFromDOF=False): - TimeIntegration.BackwardEuler.updateTimeHistory(self,resetFromDOF) - self.transport.u_dof_old[:] = self.u -class RKEV(TimeIntegration.SSP): - from proteus import TimeIntegration - """ - Wrapper for SSPRK time integration using EV - - ... more to come ... - """ - - def __init__(self, transport, timeOrder=1, runCFL=0.1, integrateInterpolationPoints=False): - TimeIntegration.SSP.__init__(self, transport, integrateInterpolationPoints=integrateInterpolationPoints) - self.runCFL = runCFL - self.dtLast = None - self.isAdaptive = True - # About the cfl - assert transport.coefficients.STABILIZATION_TYPE > 0, "SSP method just works for edge based EV methods; i.e., STABILIZATION_TYPE>0" - assert hasattr(transport, 'edge_based_cfl'), "No edge based cfl defined" - self.cfl = transport.edge_based_cfl - # Stuff particular for SSP - self.timeOrder = timeOrder # order of approximation - self.nStages = timeOrder # number of stages total - self.lstage = 0 # last stage completed - # storage vectors - self.u_dof_last = {} - # per component stage values, list with array at each stage - self.u_dof_stage = {} - for ci in range(self.nc): - if ('m', ci) in transport.q: - self.u_dof_last[ci] = transport.u[ci].dof.copy() - self.u_dof_stage[ci] = [] - for k in range(self.nStages + 1): - self.u_dof_stage[ci].append(transport.u[ci].dof.copy()) - - # def set_dt(self, DTSET): - # self.dt = DTSET # don't update t - def choose_dt(self): - comm = Comm.get() - maxCFL = 1.0e-6 - maxCFL = max(maxCFL, comm.globalMax(self.cfl.max())) - self.dt = old_div(self.runCFL, maxCFL) - if self.dtLast is None: - self.dtLast = self.dt - self.t = self.tLast + self.dt - self.substeps = [self.t for i in range(self.nStages)] # Manuel is ignoring different time step levels for now - - def initialize_dt(self, t0, tOut, q): - """ - Modify self.dt - """ - self.tLast = t0 - self.choose_dt() - self.t = t0 + self.dt - - def setCoefficients(self): - """ - beta are all 1's here - mwf not used right now - """ - self.alpha = np.zeros((self.nStages, self.nStages), 'd') - self.dcoefs = np.zeros((self.nStages), 'd') - - def updateStage(self): - """ - Need to switch to use coefficients - """ - self.lstage += 1 - assert self.timeOrder in [1, 2, 3] - assert self.lstage > 0 and self.lstage <= self.timeOrder - if self.timeOrder == 3: - if self.lstage == 1: - logEvent("First stage of SSP33 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - # update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] - elif self.lstage == 2: - logEvent("Second stage of SSP33 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - self.u_dof_stage[ci][self.lstage] *= old_div(1., 4.) - self.u_dof_stage[ci][self.lstage] += 3. / 4. * self.u_dof_last[ci] - # Update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] - elif self.lstage == 3: - logEvent("Third stage of SSP33 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - self.u_dof_stage[ci][self.lstage] *= old_div(2.0, 3.0) - self.u_dof_stage[ci][self.lstage] += 1.0 / 3.0 * self.u_dof_last[ci] - # update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_last[ci] - # update solution to u[0].dof - self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] - elif self.timeOrder == 2: - if self.lstage == 1: - logEvent("First stage of SSP22 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - # Update u_dof_old - self.transport.u_dof_old[:] = self.transport.u[ci].dof - elif self.lstage == 2: - logEvent("Second stage of SSP22 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - self.u_dof_stage[ci][self.lstage][:] *= old_div(1., 2.) - self.u_dof_stage[ci][self.lstage][:] += 1. / 2. * self.u_dof_last[ci] - # update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_last[ci] - # update solution to u[0].dof - self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] - else: - assert self.timeOrder == 1 - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof[:] - self.transport.u_dof_old[:] = self.transport.u[ci].dof - - def initializeTimeHistory(self, resetFromDOF=True): - """ - Push necessary information into time history arrays - """ - for ci in range(self.nc): - self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] - for k in range(self.nStages): - self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] - - def updateTimeHistory(self, resetFromDOF=False): - """ - assumes successful step has been taken - """ - - self.t = self.tLast + self.dt - for ci in range(self.nc): - self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] - for k in range(self.nStages): - self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] - self.lstage = 0 - self.dtLast = self.dt - self.tLast = self.t - - def generateSubsteps(self, tList): - """ - create list of substeps over time values given in tList. These correspond to stages - """ - self.substeps = [] - tLast = self.tLast - for t in tList: - dttmp = t - tLast - self.substeps.extend([tLast + dttmp for i in range(self.nStages)]) - tLast = t - - def resetOrder(self, order): - """ - initialize data structures for stage updges - """ - self.timeOrder = order # order of approximation - self.nStages = order # number of stages total - self.lstage = 0 # last stage completed - # storage vectors - # per component stage values, list with array at each stage - self.u_dof_stage = {} - for ci in range(self.nc): - if ('m', ci) in self.transport.q: - self.u_dof_stage[ci] = [] - for k in range(self.nStages + 1): - self.u_dof_stage[ci].append(self.transport.u[ci].dof.copy()) - self.substeps = [self.t for i in range(self.nStages)] - - def setFromOptions(self, nOptions): - """ - allow classes to set various numerical parameters - """ - if 'runCFL' in dir(nOptions): - self.runCFL = nOptions.runCFL - flags = ['timeOrder'] - for flag in flags: - if flag in dir(nOptions): - val = getattr(nOptions, flag) - setattr(self, flag, val) - if flag == 'timeOrder': - self.resetOrder(self.timeOrder) - -class Coefficients(proteus.TransportCoefficients.TC_base): - """ - version of Re where element material type id's used in evals - """ - from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2 - from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchten_sd_het - def __init__(self, - nd, - Ksw_types, - vgm_n_types, - vgm_alpha_types, - thetaR_types, - thetaSR_types, - gravity, - density, - beta, - diagonal_conductivity=True, - getSeepageFace=None, - # FOR EDGE BASED EV - STABILIZATION_TYPE=0, - ENTROPY_TYPE=2, # logarithmic - LUMPED_MASS_MATRIX=False, - MONOLITHIC=True, - FCT=False, - forceStrongBoundaryConditions=False, - num_fct_iter=1, - # FOR ENTROPY VISCOSITY - cE=1.0, - uL=0.0, - uR=1.0, - # FOR ARTIFICIAL COMPRESSION - cK=1.0, - # OUTPUT quantDOFs - outputQuantDOFs=False): - variableNames=['pressure_head'] - nc=1 - mass={0:{0:'nonlinear'}} - advection={0:{0:'nonlinear'}} - diffusion={0:{0:{0:'nonlinear'}}} - potential={0:{0:'u'}} - reaction={0:{0:'linear'}} - hamiltonian={} - self.getSeepageFace=getSeepageFace - self.gravity=gravity - self.rho = density - self.beta=beta - self.vgm_n_types = vgm_n_types - self.vgm_alpha_types = vgm_alpha_types - self.thetaR_types = thetaR_types - self.thetaSR_types = thetaSR_types - self.elementMaterialTypes = None - self.exteriorElementBoundaryTypes = None - self.materialTypes_q = None - self.materialTypes_ebq = None - self.materialTypes_ebqe = None - self.nd = nd - self.nMaterialTypes = len(thetaR_types) - self.q = {}; self.ebqe = {}; self.ebq = {}; self.ebq_global={} - #try to allow some flexibility in input of permeability/conductivity tensor - self.diagonal_conductivity = diagonal_conductivity - self.Ksw_types_in = Ksw_types - if self.diagonal_conductivity: - sparseDiffusionTensors = {(0,0):(np.arange(self.nd+1,dtype='i'), - np.arange(self.nd,dtype='i'))} - - assert len(Ksw_types.shape) in [1,2], "if diagonal conductivity true then Ksw_types scalar or vector of diagonal entries" - #allow scalar input Ks - if len(Ksw_types.shape)==1: - self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd),'d') - for I in range(self.nd): - self.Ksw_types[:,I] = Ksw_types - else: - self.Ksw_types = Ksw_types - else: #full - sparseDiffusionTensors = {(0,0):(np.arange(self.nd**2+1,step=self.nd,dtype='i'), - np.array([list(range(self.nd)) for row in range(self.nd)],dtype='i'))} - assert len(Ksw_types.shape) in [1,2], "if full tensor conductivity true then Ksw_types scalar or 'flattened' row-major representation of entries" - if len(Ksw_types.shape)==1: - self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd**2),'d') - for I in range(self.nd): - self.Ksw_types[:,I*self.nd+I] = Ksw_types - else: - assert Ksw_types.shape[1] == self.nd**2 - self.Ksw_types = Ksw_types - # EDGE BASED (AND ENTROPY) VISCOSITY - self.LUMPED_MASS_MATRIX = LUMPED_MASS_MATRIX - self.MONOLITHIC = MONOLITHIC - self.STABILIZATION_TYPE = STABILIZATION_TYPE - self.ENTROPY_TYPE = ENTROPY_TYPE - self.FCT = FCT - self.num_fct_iter=num_fct_iter - self.uL = uL - self.uR = uR - self.cK = cK - self.forceStrongConditions = forceStrongBoundaryConditions - self.cE = cE - self.outputQuantDOFs = outputQuantDOFs - TC_base.__init__(self, - nc, - mass, - advection, - diffusion, - potential, - reaction, - hamiltonian, - variableNames, - sparseDiffusionTensors = sparseDiffusionTensors, - useSparseDiffusion = True) - - def initializeMesh(self,mesh): - from proteus.SubsurfaceTransportCoefficients import BlockHeterogeneousCoefficients - self.elementMaterialTypes,self.exteriorElementBoundaryTypes,self.elementBoundaryTypes = BlockHeterogeneousCoefficients(mesh).initializeMaterialTypes() - #want element boundary material types for evaluating heterogeneity - #not boundary conditions - self.isSeepageFace = np.zeros((mesh.nExteriorElementBoundaries_global),'i') - if self.getSeepageFace != None: - for ebNE in range(mesh.nExteriorElementBoundaries_global): - #mwf missing ebNE-->ebN? - ebN = mesh.exteriorElementBoundariesArray[ebNE] - #print "eb flag",mesh.elementBoundaryMaterialTypes[ebN] - #print self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) - self.isSeepageFace[ebNE] = self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) - #print self.isSeepageFace - def initializeElementQuadrature(self,t,cq): - self.materialTypes_q = self.elementMaterialTypes - self.q_shape = cq[('u',0)].shape -# cq['Ks'] = np.zeros(self.q_shape,'d') -# for k in range(self.q_shape[1]): -# cq['Ks'][:,k] = self.Ksw_types[self.elementMaterialTypes,0] - self.q[('vol_frac',0)] = np.zeros(self.q_shape,'d') - def initializeElementBoundaryQuadrature(self,t,cebq,cebq_global): - self.materialTypes_ebq = np.zeros(cebq[('u',0)].shape[0:2],'i') - self.ebq_shape = cebq[('u',0)].shape - for ebN_local in range(self.ebq_shape[1]): - self.materialTypes_ebq[:,ebN_local] = self.elementMaterialTypes - self.ebq[('vol_frac',0)] = np.zeros(self.ebq_shape,'d') - - def initializeGlobalExteriorElementBoundaryQuadrature(self,t,cebqe): - self.materialTypes_ebqe = self.exteriorElementBoundaryTypes - self.ebqe_shape = cebqe[('u',0)].shape - self.ebqe[('vol_frac',0)] = np.zeros(self.ebqe_shape,'d') - # - def evaluate(self,t,c): - if c[('u',0)].shape == self.q_shape: - materialTypes = self.materialTypes_q - vol_frac = self.q[('vol_frac',0)] - elif c[('u',0)].shape == self.ebqe_shape: - materialTypes = self.materialTypes_ebqe - vol_frac = self.ebqe[('vol_frac',0)] - elif c[('u',0)].shape == self.ebq_shape: - materialTypes = self.materialTypes_ebq - vol_frac = self.ebq[('vol_frac',0)] - else: - assert False, "no materialType found to match c[('u',0)].shape= %s " % c[('u',0)].shape - self.conservativeHeadRichardsMualemVanGenuchten_sd_het(self.sdInfo[(0,0)][0], - self.sdInfo[(0,0)][1], - materialTypes, - self.rho, - self.beta, - self.gravity, - self.vgm_alpha_types, - self.vgm_n_types, - self.thetaR_types, - self.thetaSR_types, - self.Ksw_types, - c[('u',0)], - c[('m',0)], - c[('dm',0,0)], - c[('f',0)], - c[('df',0,0)], - c[('a',0,0)], - c[('da',0,0,0)], - vol_frac) - # print "Picard---------------------------------------------------------------" - # c[('df',0,0)][:] = 0.0 - # c[('da',0,0,0)][:] = 0.0 -# self.conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2(materialTypes, -# self.rho, -# self.beta, -# self.gravity, -# self.vgm_alpha_types, -# self.vgm_n_types, -# self.thetaR_types, -# self.thetaSR_types, -# self.Ksw_types, -# c[('u',0)], -# c[('m',0)], -# c[('dm',0,0)], -# c[('f',0)], -# c[('df',0,0)], -# c[('a',0,0)], -# c[('da',0,0,0)]) - #mwf debug - if (np.isnan(c[('da',0,0,0)]).any() or - np.isnan(c[('a',0,0)]).any() or - np.isnan(c[('df',0,0)]).any() or - np.isnan(c[('f',0)]).any() or - np.isnan(c[('u',0)]).any() or - np.isnan(c[('m',0)]).any() or - np.isnan(c[('dm',0,0)]).any()): - import pdb - pdb.set_trace() - -# #mwf debug -# if c[('u',0)].shape == self.q_shape: -# c[('visPerm',0)]=c[('a',0,0)][:,:,0,0] - -class LevelModel(proteus.Transport.OneLevelTransport): - nCalls=0 - def __init__(self, - uDict, - phiDict, - testSpaceDict, - matType, - dofBoundaryConditionsDict, - dofBoundaryConditionsSetterDict, - coefficients, - elementQuadrature, - elementBoundaryQuadrature, - fluxBoundaryConditionsDict=None, - advectiveFluxBoundaryConditionsSetterDict=None, - diffusiveFluxBoundaryConditionsSetterDictDict=None, - stressTraceBoundaryConditionsSetterDict=None, - stabilization=None, - shockCapturing=None, - conservativeFluxDict=None, - numericalFluxType=None, - TimeIntegrationClass=None, - massLumping=False, - reactionLumping=False, - options=None, - name='defaultName', - reuse_trial_and_test_quadrature=True, - sd = True, - movingDomain=False, - bdyNullSpace=False): - self.bdyNullSpace=bdyNullSpace - # - #set the objects describing the method and boundary conditions - # - self.movingDomain=movingDomain - self.tLast_mesh=None - # - self.name=name - self.sd=sd - self.Hess=False - self.lowmem=True - self.timeTerm=True#allow turning off the time derivative - #self.lowmem=False - self.testIsTrial=True - self.phiTrialIsTrial=True - self.u = uDict - self.ua = {}#analytical solutions - self.phi = phiDict - self.dphi={} - self.matType = matType - #mwf try to reuse test and trial information across components if spaces are the same - self.reuse_test_trial_quadrature = reuse_trial_and_test_quadrature#True#False - if self.reuse_test_trial_quadrature: - for ci in range(1,coefficients.nc): - assert self.u[ci].femSpace.__class__.__name__ == self.u[0].femSpace.__class__.__name__, "to reuse_test_trial_quad all femSpaces must be the same!" - self.u_dof_old = None - ## Simplicial Mesh - self.mesh = self.u[0].femSpace.mesh #assume the same mesh for all components for now - self.testSpace = testSpaceDict - self.dirichletConditions = dofBoundaryConditionsDict - self.dirichletNodeSetList=None #explicit Dirichlet conditions for now, no Dirichlet BC constraints - self.coefficients = coefficients - self.coefficients.initializeMesh(self.mesh) - self.nc = self.coefficients.nc - self.stabilization = stabilization - self.shockCapturing = shockCapturing - self.conservativeFlux = conservativeFluxDict #no velocity post-processing for now - self.fluxBoundaryConditions=fluxBoundaryConditionsDict - self.advectiveFluxBoundaryConditionsSetterDict=advectiveFluxBoundaryConditionsSetterDict - self.diffusiveFluxBoundaryConditionsSetterDictDict = diffusiveFluxBoundaryConditionsSetterDictDict - #determine whether the stabilization term is nonlinear - self.stabilizationIsNonlinear = False - #cek come back - if self.stabilization != None: - for ci in range(self.nc): - if ci in coefficients.mass: - for flag in list(coefficients.mass[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.advection: - for flag in list(coefficients.advection[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.diffusion: - for diffusionDict in list(coefficients.diffusion[ci].values()): - for flag in list(diffusionDict.values()): - if flag != 'constant': - self.stabilizationIsNonlinear=True - if ci in coefficients.potential: - for flag in list(coefficients.potential[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.reaction: - for flag in list(coefficients.reaction[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.hamiltonian: - for flag in list(coefficients.hamiltonian[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - #determine if we need element boundary storage - self.elementBoundaryIntegrals = {} - for ci in range(self.nc): - self.elementBoundaryIntegrals[ci] = ((self.conservativeFlux != None) or - (numericalFluxType != None) or - (self.fluxBoundaryConditions[ci] == 'outFlow') or - (self.fluxBoundaryConditions[ci] == 'mixedFlow') or - (self.fluxBoundaryConditions[ci] == 'setFlow')) - # - #calculate some dimensions - # - self.nSpace_global = self.u[0].femSpace.nSpace_global #assume same space dim for all variables - self.nDOF_trial_element = [u_j.femSpace.max_nDOF_element for u_j in list(self.u.values())] - self.nDOF_phi_trial_element = [phi_k.femSpace.max_nDOF_element for phi_k in list(self.phi.values())] - self.n_phi_ip_element = [phi_k.femSpace.referenceFiniteElement.interpolationConditions.nQuadraturePoints for phi_k in list(self.phi.values())] - self.nDOF_test_element = [femSpace.max_nDOF_element for femSpace in list(self.testSpace.values())] - self.nFreeDOF_global = [dc.nFreeDOF_global for dc in list(self.dirichletConditions.values())] - self.nVDOF_element = sum(self.nDOF_trial_element) - self.nFreeVDOF_global = sum(self.nFreeDOF_global) - # - NonlinearEquation.__init__(self,self.nFreeVDOF_global) - # - #build the quadrature point dictionaries from the input (this - #is just for convenience so that the input doesn't have to be - #complete) - # - elementQuadratureDict={} - elemQuadIsDict = isinstance(elementQuadrature,dict) - if elemQuadIsDict: #set terms manually - for I in self.coefficients.elementIntegralKeys: - if I in elementQuadrature: - elementQuadratureDict[I] = elementQuadrature[I] - else: - elementQuadratureDict[I] = elementQuadrature['default'] - else: - for I in self.coefficients.elementIntegralKeys: - elementQuadratureDict[I] = elementQuadrature - if self.stabilization != None: - for I in self.coefficients.elementIntegralKeys: - if elemQuadIsDict: - if I in elementQuadrature: - elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature[I] - else: - elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature['default'] - else: - elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature - if self.shockCapturing != None: - for ci in self.shockCapturing.components: - if elemQuadIsDict: - if ('numDiff',ci,ci) in elementQuadrature: - elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature[('numDiff',ci,ci)] - else: - elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature['default'] - else: - elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature - if massLumping: - for ci in list(self.coefficients.mass.keys()): - elementQuadratureDict[('m',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - for I in self.coefficients.elementIntegralKeys: - elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - if reactionLumping: - for ci in list(self.coefficients.mass.keys()): - elementQuadratureDict[('r',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - for I in self.coefficients.elementIntegralKeys: - elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - elementBoundaryQuadratureDict={} - if isinstance(elementBoundaryQuadrature,dict): #set terms manually - for I in self.coefficients.elementBoundaryIntegralKeys: - if I in elementBoundaryQuadrature: - elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature[I] - else: - elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature['default'] - else: - for I in self.coefficients.elementBoundaryIntegralKeys: - elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature - # - # find the union of all element quadrature points and - # build a quadrature rule for each integral that has a - # weight at each point in the union - #mwf include tag telling me which indices are which quadrature rule? - (self.elementQuadraturePoints,self.elementQuadratureWeights, - self.elementQuadratureRuleIndeces) = Quadrature.buildUnion(elementQuadratureDict) - self.nQuadraturePoints_element = self.elementQuadraturePoints.shape[0] - self.nQuadraturePoints_global = self.nQuadraturePoints_element*self.mesh.nElements_global - # - #Repeat the same thing for the element boundary quadrature - # - (self.elementBoundaryQuadraturePoints, - self.elementBoundaryQuadratureWeights, - self.elementBoundaryQuadratureRuleIndeces) = Quadrature.buildUnion(elementBoundaryQuadratureDict) - self.nElementBoundaryQuadraturePoints_elementBoundary = self.elementBoundaryQuadraturePoints.shape[0] - self.nElementBoundaryQuadraturePoints_global = (self.mesh.nElements_global* - self.mesh.nElementBoundaries_element* - self.nElementBoundaryQuadraturePoints_elementBoundary) -# if isinstance(self.u[0].femSpace,C0_AffineLinearOnSimplexWithNodalBasis): -# print self.nQuadraturePoints_element -# if self.nSpace_global == 3: -# assert(self.nQuadraturePoints_element == 5) -# elif self.nSpace_global == 2: -# assert(self.nQuadraturePoints_element == 6) -# elif self.nSpace_global == 1: -# assert(self.nQuadraturePoints_element == 3) -# -# print self.nElementBoundaryQuadraturePoints_elementBoundary -# if self.nSpace_global == 3: -# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) -# elif self.nSpace_global == 2: -# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) -# elif self.nSpace_global == 1: -# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 1) - - # - #storage dictionaries - self.scalars_element = set() - # - #simplified allocations for test==trial and also check if space is mixed or not - # - self.q={} - self.ebq={} - self.ebq_global={} - self.ebqe={} - self.phi_ip={} - self.edge_based_cfl = np.zeros(self.u[0].dof.shape)+100 - #mesh - #self.q['x'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,3),'d') - self.q[('dV_u', 0)] = (old_div(1.0, self.mesh.nElements_global)) * np.ones((self.mesh.nElements_global, self.nQuadraturePoints_element), 'd') - self.ebqe['x'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,3),'d') - self.q[('u',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') - self.q[('grad(u)',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') - self.q['velocity'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') - self.q[('m',0)] = self.q[('u',0)].copy() - self.q[('mt',0)] = self.q[('u',0)].copy() - self.q[('m_last',0)] = self.q[('u',0)].copy() - self.q[('m_tmp',0)] = self.q[('u',0)].copy() - self.q[('cfl',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') - self.q[('numDiff',0,0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') - self.ebqe[('u',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.ebqe[('grad(u)',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') - self.ebqe['velocity'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') - self.ebqe[('advectiveFlux_bc_flag',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'i') - self.ebqe[('advectiveFlux_bc',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.ebqe[('advectiveFlux',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.ebqe[('penalty')] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.points_elementBoundaryQuadrature= set() - self.scalars_elementBoundaryQuadrature= set([('u',ci) for ci in range(self.nc)]) - self.vectors_elementBoundaryQuadrature= set() - self.tensors_elementBoundaryQuadrature= set() - self.inflowBoundaryBC = {} - self.inflowBoundaryBC_values = {} - self.inflowFlux = {} - for cj in range(self.nc): - self.inflowBoundaryBC[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,),'i') - self.inflowBoundaryBC_values[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nDOF_trial_element[cj]),'d') - self.inflowFlux[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.internalNodes = set(range(self.mesh.nNodes_global)) - #identify the internal nodes this is ought to be in mesh - ##\todo move this to mesh - for ebNE in range(self.mesh.nExteriorElementBoundaries_global): - ebN = self.mesh.exteriorElementBoundariesArray[ebNE] - eN_global = self.mesh.elementBoundaryElementsArray[ebN,0] - ebN_element = self.mesh.elementBoundaryLocalElementBoundariesArray[ebN,0] - for i in range(self.mesh.nNodes_element): - if i != ebN_element: - I = self.mesh.elementNodesArray[eN_global,i] - self.internalNodes -= set([I]) - self.nNodes_internal = len(self.internalNodes) - self.internalNodesArray=np.zeros((self.nNodes_internal,),'i') - for nI,n in enumerate(self.internalNodes): - self.internalNodesArray[nI]=n - # - del self.internalNodes - self.internalNodes = None - logEvent("Updating local to global mappings",2) - self.updateLocal2Global() - logEvent("Building time integration object",2) - logEvent(memory("inflowBC, internalNodes,updateLocal2Global","OneLevelTransport"),level=4) - #mwf for interpolating subgrid error for gradients etc - if self.stabilization and self.stabilization.usesGradientStabilization: - self.timeIntegration = TimeIntegrationClass(self,integrateInterpolationPoints=True) - else: - self.timeIntegration = TimeIntegrationClass(self) - - if options != None: - self.timeIntegration.setFromOptions(options) - logEvent(memory("TimeIntegration","OneLevelTransport"),level=4) - logEvent("Calculating numerical quadrature formulas",2) - self.calculateQuadrature() - #lay out components/equations contiguously for now - self.offset = [0] - for ci in range(1,self.nc): - self.offset += [self.offset[ci-1]+self.nFreeDOF_global[ci-1]] - self.stride = [1 for ci in range(self.nc)] - #use contiguous layout of components for parallel, requires weak DBC's - # mql. Some ASSERTS to restrict the combination of the methods - if self.coefficients.STABILIZATION_TYPE > 0: - pass - #assert self.timeIntegration.isSSP == True, "If STABILIZATION_TYPE>0, use RKEV timeIntegration within VOF model" - #cond = 'levelNonlinearSolver' in dir(options) and (options.levelNonlinearSolver == - # ExplicitLumpedMassMatrixForRichards or options.levelNonlinearSolver == ExplicitConsistentMassMatrixForRichards) - #assert cond, "If STABILIZATION_TYPE>0, use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards or ExplicitConsistentMassMatrixForRichards" - try: - if 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards: - assert self.coefficients.LUMPED_MASS_MATRIX, "If levelNonlinearSolver=ExplicitLumpedMassMatrix, use LUMPED_MASS_MATRIX=True" - except: - pass - if self.coefficients.LUMPED_MASS_MATRIX == True: - cond = self.coefficients.STABILIZATION_TYPE == 2 - assert cond, "Use lumped mass matrix just with: STABILIZATION_TYPE=2 (smoothness based stab.)" - cond = 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards - assert cond, "Use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards when the mass matrix is lumped" - if self.coefficients.FCT == True: - cond = self.coefficients.STABILIZATION_TYPE > 0, "Use FCT just with STABILIZATION_TYPE>0; i.e., edge based stabilization" - # END OF ASSERTS - - # cek adding empty data member for low order numerical viscosity structures here for now - self.ML = None # lumped mass matrix - self.MC_global = None # consistent mass matrix - self.cterm_global = None - self.cterm_transpose_global = None - # dL_global and dC_global are not the full matrices but just the CSR arrays containing the non zero entries - self.residualComputed=False #TMP - self.dLow= None - self.fluxMatrix = None - self.uDotLow = None - self.uLow = None - self.dt_times_dC_minus_dL = None - self.min_s_bc = None - self.max_s_bc = None - # Aux quantity at DOFs to be filled by optimized code (MQL) - self.quantDOFs = np.zeros(self.u[0].dof.shape, 'd') - self.sLow = np.zeros(self.u[0].dof.shape, 'd') - self.sHigh = np.zeros(self.u[0].dof.shape, 'd') - self.sn = np.zeros(self.u[0].dof.shape, 'd') - comm = Comm.get() - self.comm=comm - if comm.size() > 1: - assert numericalFluxType != None and numericalFluxType.useWeakDirichletConditions,"You must use a numerical flux to apply weak boundary conditions for parallel runs" - self.offset = [0] - for ci in range(1,self.nc): - self.offset += [ci] - self.stride = [self.nc for ci in range(self.nc)] - # - logEvent(memory("stride+offset","OneLevelTransport"),level=4) - if numericalFluxType != None: - if options is None or options.periodicDirichletConditions is None: - self.numericalFlux = numericalFluxType(self, - dofBoundaryConditionsSetterDict, - advectiveFluxBoundaryConditionsSetterDict, - diffusiveFluxBoundaryConditionsSetterDictDict) - else: - self.numericalFlux = numericalFluxType(self, - dofBoundaryConditionsSetterDict, - advectiveFluxBoundaryConditionsSetterDict, - diffusiveFluxBoundaryConditionsSetterDictDict, - options.periodicDirichletConditions) - else: - self.numericalFlux = None - #set penalty terms - #cek todo move into numerical flux initialization - if 'penalty' in self.ebq_global: - for ebN in range(self.mesh.nElementBoundaries_global): - for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): - self.ebq_global['penalty'][ebN,k] = old_div(self.numericalFlux.penalty_constant,(self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power)) - #penalty term - #cek move to Numerical flux initialization - if 'penalty' in self.ebqe: - for ebNE in range(self.mesh.nExteriorElementBoundaries_global): - ebN = self.mesh.exteriorElementBoundariesArray[ebNE] - for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): - self.ebqe['penalty'][ebNE,k] = old_div(self.numericalFlux.penalty_constant,self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power) - logEvent(memory("numericalFlux","OneLevelTransport"),level=4) - self.elementEffectiveDiametersArray = self.mesh.elementInnerDiametersArray - #use post processing tools to get conservative fluxes, None by default - from proteus import PostProcessingTools - self.velocityPostProcessor = PostProcessingTools.VelocityPostProcessingChooser(self) - logEvent(memory("velocity postprocessor","OneLevelTransport"),level=4) - #helper for writing out data storage - from proteus import Archiver - self.elementQuadratureDictionaryWriter = Archiver.XdmfWriter() - self.elementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() - self.exteriorElementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() - #TODO get rid of this - for ci,fbcObject in list(self.fluxBoundaryConditionsObjectsDict.items()): - self.ebqe[('advectiveFlux_bc_flag',ci)] = np.zeros(self.ebqe[('advectiveFlux_bc',ci)].shape,'i') - for t,g in list(fbcObject.advectiveFluxBoundaryConditionsDict.items()): - if ci in self.coefficients.advection: - self.ebqe[('advectiveFlux_bc',ci)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) - self.ebqe[('advectiveFlux_bc_flag',ci)][t[0],t[1]] = 1 - - if hasattr(self.numericalFlux,'setDirichletValues'): - self.numericalFlux.setDirichletValues(self.ebqe) - if not hasattr(self.numericalFlux,'isDOFBoundary'): - self.numericalFlux.isDOFBoundary = {0:np.zeros(self.ebqe[('u',0)].shape,'i')} - if not hasattr(self.numericalFlux,'ebqe'): - self.numericalFlux.ebqe = {('u',0):np.zeros(self.ebqe[('u',0)].shape,'d')} - #TODO how to handle redistancing calls for calculateCoefficients,calculateElementResidual etc - self.globalResidualDummy = None - compKernelFlag=0 - self.delta_x_ij=None - self.richards = cRichards_base(self.nSpace_global, - self.nQuadraturePoints_element, - self.u[0].femSpace.elementMaps.localFunctionSpace.dim, - self.u[0].femSpace.referenceFiniteElement.localFunctionSpace.dim, - self.testSpace[0].referenceFiniteElement.localFunctionSpace.dim, - self.nElementBoundaryQuadraturePoints_elementBoundary, - compKernelFlag) - if self.movingDomain: - self.MOVING_DOMAIN=1.0 - else: - self.MOVING_DOMAIN=0.0 - #cek hack - self.movingDomain=False - self.MOVING_DOMAIN=0.0 - if self.mesh.nodeVelocityArray is None: - self.mesh.nodeVelocityArray = np.zeros(self.mesh.nodeArray.shape,'d') - self.forceStrongConditions=self.coefficients.forceStrongConditions - self.dirichletConditionsForceDOF = {} - if self.forceStrongConditions: - for cj in range(self.nc): - self.dirichletConditionsForceDOF[cj] = DOFBoundaryConditions(self.u[cj].femSpace,dofBoundaryConditionsSetterDict[cj],weakDirichletConditions=False) - def FCTStep(self): - import pdb - rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() - limited_solution = np.zeros((len(rowptr) - 1),'d') - #self.u_free_dof_stage_0_l = np.zeros((len(rowptr) - 1),'d') - #self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage], # soln - #fromFreeToGlobal=0 - #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - # self.offset[0], - # self.stride[0], - # self.dirichletConditions[0].global2freeGlobal_global_dofs, - # self.dirichletConditions[0].global2freeGlobal_free_dofs, - # self.u_free_dof_stage_0_l, - # self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage]) - argsDict = cArgumentsDict.ArgumentsDict() - argsDict["bc_mask"] = self.bc_mask - argsDict["NNZ"] = self.nnz - argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs - argsDict["dt"] = self.timeIntegration.dt - argsDict["lumped_mass_matrix"] = self.ML - argsDict["soln"] = self.sn - argsDict["pn"] = self.u[0].dof - argsDict["solH"] = self.sHigh - argsDict["uLow"] = self.sLow - argsDict["uDotLow"] = self.uDotLow - argsDict["limited_solution"] = limited_solution - argsDict["csrRowIndeces_DofLoops"] = rowptr - argsDict["csrColumnOffsets_DofLoops"] = colind - argsDict["MassMatrix"] = MassMatrix - argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL - argsDict["min_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0]) #cek hack just set from physical bounds - argsDict["max_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0] + self.coefficients.thetaSR_types[0]) #cek hack - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - argsDict["MONOLITHIC"] =0#cek hack self.coefficients.MONOLITHIC - #pdb.set_trace() - self.richards.FCTStep(argsDict) - - # self.nnz, # number of non zero entries - # len(rowptr) - 1, # number of DOFs - # self.timeIntegration.dt, - # self.ML, # Lumped mass matrix - # self.sn, - # self.u_dof_old, - # self.sHigh, # high order solution - # self.sLow, - # limited_solution, - # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) - # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) - # MassMatrix, - # self.dt_times_dC_minus_dL, - # self.min_s_bc, - # self.max_s_bc, - # self.coefficients.LUMPED_MASS_MATRIX, - # self.coefficients.MONOLITHIC) - old_dof = self.u[0].dof.copy() - self.invert(limited_solution, self.u[0].dof) - self.timeIntegration.u[:] = self.u[0].dof - #fromFreeToGlobal=1 #direction copying - #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - # self.offset[0], - # self.stride[0], - # self.dirichletConditions[0].global2freeGlobal_global_dofs, - # self.dirichletConditions[0].global2freeGlobal_free_dofs, - # self.u[0].dof, - # limited_solution) - def kth_FCT_step(self): - #import pdb - #pdb.set_trace() - rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() - limitedFlux = np.zeros(self.nnz) - limited_solution = np.zeros((len(rowptr) - 1),'d') - #limited_solution[:] = self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage] - fromFreeToGlobal=0 #direction copying - cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - self.offset[0], - self.stride[0], - self.dirichletConditions[0].global2freeGlobal_global_dofs, - self.dirichletConditions[0].global2freeGlobal_free_dofs, - limited_solution, - self.timeintegration.u_dof_stage[0][self.timeIntegration.lstage]) - - self.richards.kth_FCT_step( - self.timeIntegration.dt, - self.coefficients.num_fct_iter, - self.nnz, # number of non zero entries - len(rowptr) - 1, # number of DOFs - MassMatrix, - self.ML, # Lumped mass matrix - self.u_dof_old, - limited_solution, - self.uDotLow, - self.uLow, - self.dLow, - self.fluxMatrix, - limitedFlux, - rowptr, - colind) - - self.timeIntegration.u[:] = limited_solution - #self.u[0].dof[:] = limited_solution - fromFreeToGlobal=1 #direction copying - cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - self.offset[0], - self.stride[0], - self.dirichletConditions[0].global2freeGlobal_global_dofs, - self.dirichletConditions[0].global2freeGlobal_free_dofs, - self.u[0].dof, - limited_solution) - def calculateCoefficients(self): - pass - def calculateElementResidual(self): - if self.globalResidualDummy != None: - self.getResidual(self.u[0].dof,self.globalResidualDummy) - def getResidual(self,u,r): - import pdb - import copy - """ - Calculate the element residuals and add in to the global residual - """ - cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, - self.jacobian) - if self.u_dof_old is None: - # Pass initial condition to u_dof_old - self.u_dof_old = np.copy(self.u[0].dof) - rowptr, colind, nzval = self.jacobian.getCSRrepresentation() - nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix - r.fill(0.0) - ######################## - ### COMPUTE C MATRIX ### - ######################## - if self.cterm_global is None: - # since we only need cterm_global to persist, we can drop the other self.'s - self.cterm = {} - self.cterm_a = {} - self.cterm_global = {} - self.cterm_transpose = {} - self.cterm_a_transpose = {} - self.cterm_global_transpose = {} - rowptr, colind, nzval = self.jacobian.getCSRrepresentation() - nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix - di = self.q[('grad(u)', 0)].copy() # direction of derivative - # JACOBIANS (FOR ELEMENT TRANSFORMATION) - self.q[('J')] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nSpace_global, - self.nSpace_global), - 'd') - self.q[('inverse(J)')] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nSpace_global, - self.nSpace_global), - 'd') - self.q[('det(J)')] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element), - 'd') - self.u[0].femSpace.elementMaps.getJacobianValues(self.elementQuadraturePoints, - self.q['J'], - self.q['inverse(J)'], - self.q['det(J)']) - self.q['abs(det(J))'] = np.abs(self.q['det(J)']) - # SHAPE FUNCTIONS - self.q[('w', 0)] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nDOF_test_element[0]), - 'd') - self.q[('w*dV_m', 0)] = self.q[('w', 0)].copy() - self.u[0].femSpace.getBasisValues(self.elementQuadraturePoints, self.q[('w', 0)]) - cfemIntegrals.calculateWeightedShape(self.elementQuadratureWeights[('u', 0)], - self.q['abs(det(J))'], - self.q[('w', 0)], - self.q[('w*dV_m', 0)]) - # GRADIENT OF TEST FUNCTIONS - self.q[('grad(w)', 0)] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nDOF_test_element[0], - self.nSpace_global), - 'd') - self.u[0].femSpace.getBasisGradientValues(self.elementQuadraturePoints, - self.q['inverse(J)'], - self.q[('grad(w)', 0)]) - self.q[('grad(w)*dV_f', 0)] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nDOF_test_element[0], - self.nSpace_global), - 'd') - cfemIntegrals.calculateWeightedShapeGradients(self.elementQuadratureWeights[('u', 0)], - self.q['abs(det(J))'], - self.q[('grad(w)', 0)], - self.q[('grad(w)*dV_f', 0)]) - ########################## - ### LUMPED MASS MATRIX ### - ########################## - # assume a linear mass term - dm = np.ones(self.q[('u', 0)].shape, 'd') - elementMassMatrix = np.zeros((self.mesh.nElements_global, - self.nDOF_test_element[0], - self.nDOF_trial_element[0]), 'd') - cfemIntegrals.updateMassJacobian_weak_lowmem(dm, - self.q[('w', 0)], - self.q[('w*dV_m', 0)], - elementMassMatrix) - self.MC_a = nzval.copy() - self.MC_global = SparseMat(self.nFreeDOF_global[0], - self.nFreeDOF_global[0], - nnz, - self.MC_a, - colind, - rowptr) - cfemIntegrals.zeroJacobian_CSR(self.nnz, self.MC_global) - cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.csrRowIndeces[(0, 0)], - self.csrColumnOffsets[(0, 0)], - elementMassMatrix, - self.MC_global) - self.ML = np.zeros((self.nFreeDOF_global[0],), 'd') - for i in range(self.nFreeDOF_global[0]): - self.ML[i] = self.MC_a[rowptr[i]:rowptr[i + 1]].sum() - np.testing.assert_almost_equal(self.ML.sum(), - self.mesh.volume, - err_msg="Trace of lumped mass matrix should be the domain volume", verbose=True) - for d in range(self.nSpace_global): # spatial dimensions - # C matrices - self.cterm[d] = np.zeros((self.mesh.nElements_global, - self.nDOF_test_element[0], - self.nDOF_trial_element[0]), 'd') - self.cterm_a[d] = nzval.copy() - #self.cterm_a[d] = np.zeros(nzval.size) - self.cterm_global[d] = SparseMat(self.nFreeDOF_global[0], - self.nFreeDOF_global[0], - nnz, - self.cterm_a[d], - colind, - rowptr) - cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global[d]) - di[:] = 0.0 - di[..., d] = 1.0 - cfemIntegrals.updateHamiltonianJacobian_weak_lowmem(di, - self.q[('grad(w)*dV_f', 0)], - self.q[('w', 0)], - self.cterm[d]) # int[(di*grad(wj))*wi*dV] - cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.csrRowIndeces[(0, 0)], - self.csrColumnOffsets[(0, 0)], - self.cterm[d], - self.cterm_global[d]) - # C Transpose matrices - self.cterm_transpose[d] = np.zeros((self.mesh.nElements_global, - self.nDOF_test_element[0], - self.nDOF_trial_element[0]), 'd') - self.cterm_a_transpose[d] = nzval.copy() - self.cterm_global_transpose[d] = SparseMat(self.nFreeDOF_global[0], - self.nFreeDOF_global[0], - nnz, - self.cterm_a_transpose[d], - colind, - rowptr) - cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global_transpose[d]) - di[:] = 0.0 - di[..., d] = -1.0 - cfemIntegrals.updateAdvectionJacobian_weak_lowmem(di, - self.q[('w', 0)], - self.q[('grad(w)*dV_f', 0)], - self.cterm_transpose[d]) # -int[(-di*grad(wi))*wj*dV] - cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.csrRowIndeces[(0, 0)], - self.csrColumnOffsets[(0, 0)], - self.cterm_transpose[d], - self.cterm_global_transpose[d]) - - rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() - else: - Cy = np.zeros(Cx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() - else: - Cz = np.zeros(Cx.shape, 'd') - rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() - else: - CTy = np.zeros(CTx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() - else: - CTz = np.zeros(CTx.shape, 'd') - - # This is dummy. I just care about the csr structure of the sparse matrix - self.dLow = np.zeros(Cx.shape, 'd') - self.fluxMatrix = np.zeros(Cx.shape, 'd') - self.dt_times_dC_minus_dL = np.zeros(Cx.shape, 'd') - nFree = len(rowptr)-1 - self.min_s_bc = np.zeros(nFree, 'd') + 1E10 - self.max_s_bc = np.zeros(nFree, 'd') - 1E10 - self.uDotLow = np.zeros(nFree, 'd') - self.uLow = np.zeros(nFree, 'd') - # - # cek end computationa of cterm_global - # - # cek showing mquezada an example of using cterm_global sparse matrix - # calculation y = c*x where x==1 - # direction=0 - #rowptr, colind, c = self.cterm_global[direction].getCSRrepresentation() - #y = np.zeros((self.nFreeDOF_global[0],),'d') - #x = np.ones((self.nFreeDOF_global[0],),'d') - # ij=0 - # for i in range(self.nFreeDOF_global[0]): - # for offset in range(rowptr[i],rowptr[i+1]): - # j = colind[offset] - # y[i] += c[ij]*x[j] - # ij+=1 - #Load the unknowns into the finite element dof - self.timeIntegration.calculateCoefs() - self.timeIntegration.calculateU(u) - self.setUnknowns(self.timeIntegration.u) - #cek can put in logic to skip of BC's don't depend on t or u - #Dirichlet boundary conditions - self.numericalFlux.setDirichletValues(self.ebqe) - #flux boundary conditions - #cek hack, just using advective flux for flux BC for now - for t,g in list(self.fluxBoundaryConditionsObjectsDict[0].advectiveFluxBoundaryConditionsDict.items()): - self.ebqe[('advectiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) - self.ebqe[('advectiveFlux_bc_flag',0)][t[0],t[1]] = 1 - # for t,g in self.fluxBoundaryConditionsObjectsDict[0].diffusiveFluxBoundaryConditionsDict.iteritems(): - # self.ebqe[('diffusiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) - # self.ebqe[('diffusiveFlux_bc_flag',0)][t[0],t[1]] = 1 - #self.shockCapturing.lag=True - if self.forceStrongConditions: - self.bc_mask = np.ones_like(self.u[0].dof) - for cj in range(len(self.dirichletConditionsForceDOF)): - for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): - self.u[cj].dof[dofN] = g(self.dirichletConditionsForceDOF[cj].DOFBoundaryPointDict[dofN],self.timeIntegration.t) - self.u_dof_old[dofN] = self.u[cj].dof[dofN] - self.bc_mask[dofN] = 0.0 - degree_polynomial = 1 - try: - degree_polynomial = self.u[0].femSpace.order - except: - pass - - argsDict = cArgumentsDict.ArgumentsDict() - if self.forceStrongConditions: - argsDict["bc_mask"] = self.bc_mask - argsDict["dt"] = self.timeIntegration.dt - argsDict["Theta"] = 1.0 - argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi - argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi - argsDict["mesh_dof"] = self.mesh.nodeArray - argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray - argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN - argsDict["mesh_l2g"] = self.mesh.elementNodesArray - argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] - argsDict["u_trial_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi - argsDict["u_test_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi - argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace - argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace - argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] - argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals - argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians - argsDict["nElements_global"] = self.mesh.nElements_global - argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] - argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, - argsDict["isSeepageFace"] = self.coefficients.isSeepageFace - argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] - argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] - argsDict["rho"] = self.coefficients.rho - argsDict["beta"] = self.coefficients.beta - argsDict["gravity"] = self.coefficients.gravity - argsDict["alpha"] = self.coefficients.vgm_alpha_types - argsDict["n"] = self.coefficients.vgm_n_types - argsDict["thetaR"] = self.coefficients.thetaR_types - argsDict["thetaSR"] = self.coefficients.thetaSR_types - argsDict["KWs"] = self.coefficients.Ksw_types - argsDict["useMetrics"] = 0.0 - argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf - argsDict["lag_shockCapturing"] = 0 - argsDict["shockCapturingDiffusion"] = 0.0 - argsDict["sc_uref"] = 0.0 - argsDict["sc_alpha"] = 0.0 - argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g - argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] - argsDict["elementDiameter"] = self.mesh.elementDiametersArray - argsDict["degree_polynomial"] = degree_polynomial - argsDict["u_dof"] = self.u[0].dof - argsDict["u_dof_old"] = self.u_dof_old - argsDict["velocity"] = self.q['velocity'] - argsDict["q_m"] = self.timeIntegration.m_tmp[0] - argsDict["q_u"] = self.q[('u',0)] - argsDict["q_dV"] = self.q[('dV_u',0)] - argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] - argsDict["cfl"] = self.q[('cfl',0)] - argsDict["q_numDiff_u"] = self.q[('cfl',0)] - argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] - argsDict["offset_u"] = self.offset[0] - argsDict["stride_u"] = self.stride[0] - argsDict["globalResidual"] = r - argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global - argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray - argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray - argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray - argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] - argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] - argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] - argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] - argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] - argsDict["ebqe_phi"] = self.ebqe[('u',0)] - argsDict["epsFact"] = 0.0 - argsDict["ebqe_u"] = self.ebqe[('u',0)] - argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] - argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE - # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION - argsDict["cE"] = self.coefficients.cE - argsDict["cK"] = self.coefficients.cK - # PARAMETERS FOR LOG BASED ENTROPY FUNCTION - argsDict["uL"] = self.coefficients.uL - argsDict["uR"] = self.coefficients.uR - # PARAMETERS FOR EDGE VISCOSITY - argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs - argsDict["NNZ"] = self.nnz - argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern - argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) - argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) - argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms - argsDict["globalJacobian"] = self.jacobian.getCSRrepresentation()[2] - # C matrices - argsDict["Cx"] = Cx - argsDict["Cy"] = Cy - argsDict["Cz"] = Cz - argsDict["CTx"] = CTx - argsDict["CTy"] = CTy - argsDict["CTz"] = CTz - argsDict["ML"] = self.ML - argsDict["delta_x_ij"] = self.delta_x_ij - # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE - argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE - # FLUX CORRECTED TRANSPORT - argsDict["dLow"] = self.dLow - argsDict["fluxMatrix"] = self.fluxMatrix - argsDict["uDotLow"] = self.uDotLow - argsDict["uLow"] = self.uLow - argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL - argsDict["min_s_bc"] = self.min_s_bc - argsDict["max_s_bc"] = self.max_s_bc - argsDict["quantDOFs"] = self.quantDOFs - argsDict["sLow"] = self.sLow - argsDict["sn"] = self.sn - if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG - self.calculateResidual = self.richards.calculateResidual - self.calculateJacobian = self.richards.calculateJacobian - else: - self.calculateResidual = self.richards.calculateResidual_entropy_viscosity - self.calculateJacobian = self.richards.calculateMassMatrix - if self.delta_x_ij is None: - self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') - self.calculateResidual(argsDict) - #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] - #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf - #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] - #self.timeIntegration.calculateElementCoefficients(self.q) - if self.forceStrongConditions:# - for cj in range(len(self.dirichletConditionsForceDOF)):# - for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): - r[self.offset[cj]+self.stride[cj]*dofN] = 0 - if self.stabilization: - self.stabilization.accumulateSubgridMassHistory(self.q) - logEvent("Global residual",level=9,data=r) - self.nonlinear_function_evaluations += 1 - if self.globalResidualDummy is None: - self.globalResidualDummy = np.zeros(r.shape,'d') - - def invert(self,u,r): - #u=s - #r=p - import pdb - import copy - """ - Calculate the element residuals and add in to the global residual - """ - self.sHigh[:] = u - rowptr, colind, nzval = self.jacobian.getCSRrepresentation() - nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix - r.fill(0.0) - rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() - else: - Cy = np.zeros(Cx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() - else: - Cz = np.zeros(Cx.shape, 'd') - rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() - else: - CTy = np.zeros(CTx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() - else: - CTz = np.zeros(CTx.shape, 'd') - - # This is dummy. I just care about the csr structure of the sparse matrix - nFree = len(rowptr)-1 - degree_polynomial = 1 - try: - degree_polynomial = self.u[0].femSpace.order - except: - pass - if self.delta_x_ij is None: - self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') - argsDict = cArgumentsDict.ArgumentsDict() - argsDict["dt"] = self.timeIntegration.dt - argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi - argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi - argsDict["mesh_dof"] = self.mesh.nodeArray - argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray - argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN - argsDict["mesh_l2g"] = self.mesh.elementNodesArray - argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] - argsDict["u_trial_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi - argsDict["u_test_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi - argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace - argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace - argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] - argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals - argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians - argsDict["nElements_global"] = self.mesh.nElements_global - argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] - argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, - argsDict["isSeepageFace"] = self.coefficients.isSeepageFace - argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] - argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] - argsDict["rho"] = self.coefficients.rho - argsDict["beta"] = self.coefficients.beta - argsDict["gravity"] = self.coefficients.gravity - argsDict["alpha"] = self.coefficients.vgm_alpha_types - argsDict["n"] = self.coefficients.vgm_n_types - argsDict["thetaR"] = self.coefficients.thetaR_types - argsDict["thetaSR"] = self.coefficients.thetaSR_types - argsDict["KWs"] = self.coefficients.Ksw_types - argsDict["useMetrics"] = 0.0 - argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf - argsDict["lag_shockCapturing"] = 0 - argsDict["shockCapturingDiffusion"] = 0.0 - argsDict["sc_uref"] = 0.0 - argsDict["sc_alpha"] = 0.0 - argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g - argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] - argsDict["elementDiameter"] = self.mesh.elementDiametersArray - argsDict["degree_polynomial"] = degree_polynomial - argsDict["u_dof"] = u#self.u[0].dof - argsDict["u_dof_old"] = self.u[0].dof - argsDict["velocity"] = self.q['velocity'] - argsDict["q_m"] = self.timeIntegration.m_tmp[0] - argsDict["q_u"] = self.q[('u',0)] - argsDict["q_dV"] = self.q[('dV_u',0)] - argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] - argsDict["cfl"] = self.q[('cfl',0)] - argsDict["q_numDiff_u"] = self.q[('cfl',0)] - argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] - argsDict["offset_u"] = self.offset[0] - argsDict["stride_u"] = self.stride[0] - argsDict["globalResidual"] = r - argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global - argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray - argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray - argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray - argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] - argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] - argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] - argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] - argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] - argsDict["ebqe_phi"] = self.ebqe[('u',0)] - argsDict["epsFact"] = 0.0 - argsDict["ebqe_u"] = self.ebqe[('u',0)] - argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] - argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE - # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION - argsDict["cE"] = self.coefficients.cE - argsDict["cK"] = self.coefficients.cK - # PARAMETERS FOR LOG BASED ENTROPY FUNCTION - argsDict["uL"] = self.coefficients.uL - argsDict["uR"] = self.coefficients.uR - # PARAMETERS FOR EDGE VISCOSITY - argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs - argsDict["NNZ"] = self.nnz - argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern - argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) - argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) - argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms - # C matrices - argsDict["Cx"] = Cx - argsDict["Cy"] = Cy - argsDict["Cz"] = Cz - argsDict["CTx"] = CTx - argsDict["CTy"] = CTy - argsDict["CTz"] = CTz - argsDict["ML"] = self.ML - argsDict["delta_x_ij"] = self.delta_x_ij - # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE - argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE - # FLUX CORRECTED TRANSPORT - argsDict["dLow"] = self.dLow - argsDict["fluxMatrix"] = self.fluxMatrix - argsDict["uDotLow"] = self.uDotLow - argsDict["uLow"] = self.uLow - argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL - argsDict["min_s_bc"] = self.min_s_bc - argsDict["max_s_bc"] = self.max_s_bc - argsDict["quantDOFs"] = self.quantDOFs - argsDict["sLow"] = self.sLow - argsDict["sn"] = self.sn - self.richards.invert(argsDict) - # self.timeIntegration.dt, - # self.u[0].femSpace.elementMaps.psi, - # self.u[0].femSpace.elementMaps.grad_psi, - # self.mesh.nodeArray, - # self.mesh.nodeVelocityArray, - # self.MOVING_DOMAIN, - # self.mesh.elementNodesArray, - # self.elementQuadratureWeights[('u',0)], - # self.u[0].femSpace.psi, - # self.u[0].femSpace.grad_psi, - # self.u[0].femSpace.psi, - # self.u[0].femSpace.grad_psi, - # #element boundary - # self.u[0].femSpace.elementMaps.psi_trace, - # self.u[0].femSpace.elementMaps.grad_psi_trace, - # self.elementBoundaryQuadratureWeights[('u',0)], - # self.u[0].femSpace.psi_trace, - # self.u[0].femSpace.grad_psi_trace, - # self.u[0].femSpace.psi_trace, - # self.u[0].femSpace.grad_psi_trace, - # self.u[0].femSpace.elementMaps.boundaryNormals, - # self.u[0].femSpace.elementMaps.boundaryJacobians, - # #physics - # self.mesh.nElements_global, - # self.ebqe['penalty'],#double* ebqe_penalty_ext, - # self.mesh.elementMaterialTypes,#int* elementMaterialTypes, - # self.coefficients.isSeepageFace, - # self.coefficients.sdInfo[(0,0)][0],#int* a_rowptr, - # self.coefficients.sdInfo[(0,0)][1],#int* a_colind, - # self.coefficients.rho,#double rho, - # self.coefficients.beta,#double beta, - # self.coefficients.gravity,#double* gravity, - # self.coefficients.vgm_alpha_types,#double* alpha, - # self.coefficients.vgm_n_types,#double* n, - # self.coefficients.thetaR_types,#double* thetaR, - # self.coefficients.thetaSR_types,#double* thetaSR, - # self.coefficients.Ksw_types,#double* KWs, - # False,#self.coefficients.useMetrics, - # self.timeIntegration.alpha_bdf, - # 0,#self.shockCapturing.lag, - # 0.0,#cek hack self.shockCapturing.shockCapturingFactor, - # 0.0,#self.coefficients.sc_uref, - # 0.0,#self.coefficients.sc_beta, - # self.u[0].femSpace.dofMap.l2g, - # self.l2g[0]['freeGlobal'], - # self.mesh.elementDiametersArray, - # degree_polynomial, - # self.sHigh, - # self.u_dof_old, - # self.q['velocity'],#self.coefficients.q_v, - # self.timeIntegration.m_tmp[0], - # self.q[('u',0)], - # self.timeIntegration.beta_bdf[0], - # self.q[('cfl',0)], - # self.edge_based_cfl, - # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff[0], - # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff_last[0], - # self.offset[0],self.stride[0], - # r, - # self.mesh.nExteriorElementBoundaries_global, - # self.mesh.exteriorElementBoundariesArray, - # self.mesh.elementBoundaryElementsArray, - # self.mesh.elementBoundaryLocalElementBoundariesArray, - # self.ebqe['velocity'],#self.coefficients.ebqe_v, - # self.numericalFlux.isDOFBoundary[0], - # self.numericalFlux.ebqe[('u',0)], - # self.ebqe[('advectiveFlux_bc_flag',0)], - # self.ebqe[('advectiveFlux_bc',0)], - # self.ebqe[('u',0)],#cek hack self.coefficients.ebqe_phi, - # 0.0,#cek hack self.coefficients.epsFact, - # self.ebqe[('u',0)], - # self.ebqe[('advectiveFlux',0)], - # # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION - # self.coefficients.cE, - # self.coefficients.cK, - # # PARAMETERS FOR LOG BASED ENTROPY FUNCTION - # self.coefficients.uL, - # self.coefficients.uR, - # # PARAMETERS FOR EDGE VISCOSITY - # len(rowptr) - 1, # num of DOFs - # len(Cx), # num of non-zero entries in the sparsity pattern - # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) - # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) - # self.csrRowIndeces[(0, 0)], # row indices (convenient for element loops) - # self.csrColumnOffsets[(0, 0)], # column indices (convenient for element loops) - # self.csrColumnOffsets_eb[(0, 0)], # indices for boundary terms - # # C matrices - # Cx, - # Cy, - # Cz, - # CTx, - # CTy, - # CTz, - # self.ML, - # self.delta_x_ij, - # # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - # self.coefficients.LUMPED_MASS_MATRIX, - # self.coefficients.STABILIZATION_TYPE, - # self.coefficients.ENTROPY_TYPE, - # # FLUX CORRECTED TRANSPORT - # self.dLow, - # self.fluxMatrix, - # self.uDotLow, - # self.uLow, - # self.dt_times_dC_minus_dL, - # self.min_s_bc, - # self.max_s_bc, - # self.quantDOFs) - #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] - #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf - #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] - #self.timeIntegration.calculateElementCoefficients(self.q) - #if self.forceStrongConditions:# - # for cj in range(len(self.dirichletConditionsForceDOF)):# - # for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): - # r[self.offset[cj]+self.stride[cj]*dofN] = 0 - #if self.stabilization: - # self.stabilization.accumulateSubgridMassHistory(self.q) - #logEvent("Global residual",level=9,data=r) - #self.nonlinear_function_evaluations += 1 - #if self.globalResidualDummy is None: - # self.globalResidualDummy = numpy.zeros(r.shape,'d') - def getJacobian(self,jacobian): - if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG - cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, - jacobian) - degree_polynomial = 1 - try: - degree_polynomial = self.u[0].femSpace.order - except: - pass - if self.delta_x_ij is None: - self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') - argsDict = cArgumentsDict.ArgumentsDict() - argsDict["dt"] = self.timeIntegration.dt - argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi - argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi - argsDict["mesh_dof"] = self.mesh.nodeArray - argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray - argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN - argsDict["mesh_l2g"] = self.mesh.elementNodesArray - argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] - argsDict["u_trial_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi - argsDict["u_test_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi - argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace - argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace - argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] - argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals - argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians - argsDict["nElements_global"] = self.mesh.nElements_global - argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] - argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, - argsDict["isSeepageFace"] = self.coefficients.isSeepageFace - argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] - argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] - argsDict["rho"] = self.coefficients.rho - argsDict["beta"] = self.coefficients.beta - argsDict["gravity"] = self.coefficients.gravity - argsDict["alpha"] = self.coefficients.vgm_alpha_types - argsDict["n"] = self.coefficients.vgm_n_types - argsDict["thetaR"] = self.coefficients.thetaR_types - argsDict["thetaSR"] = self.coefficients.thetaSR_types - argsDict["KWs"] = self.coefficients.Ksw_types - argsDict["useMetrics"] = 0.0 - argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf - argsDict["lag_shockCapturing"] = 0 - argsDict["shockCapturingDiffusion"] = 0.0 - argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g - argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] - argsDict["elementDiameter"] = self.mesh.elementDiametersArray - argsDict["degree_polynomial"] = degree_polynomial - argsDict["u_dof"] = self.u[0].dof - argsDict["velocity"] = self.q['velocity'] - argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] - argsDict["cfl"] = self.q[('cfl',0)] - argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] - argsDict["csrRowIndeces_u_u"] = self.csrRowIndeces[(0,0)] - argsDict["csrColumnOffsets_u_u"] = self.csrColumnOffsets[(0,0)] - argsDict["globalJacobian"] = jacobian.getCSRrepresentation()[2] - argsDict["delta_x_ij"] = self.delta_x_ij - argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global - argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray - argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray - argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray - argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] - argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] - argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] - argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] - argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] - argsDict["csrColumnOffsets_eb_u_u"] = self.csrColumnOffsets_eb[(0,0)] - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - self.calculateJacobian(argsDict) - if self.forceStrongConditions: - for dofN in list(self.dirichletConditionsForceDOF[0].DOFBoundaryConditionsDict.keys()): - global_dofN = self.offset[0]+self.stride[0]*dofN - self.nzval[np.where(self.colind == global_dofN)] = 0.0 #column - self.nzval[self.rowptr[global_dofN]:self.rowptr[global_dofN+1]] = 0.0 #row - zeroRow=True - for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]):#row - if (self.colind[i] == global_dofN): - self.nzval[i] = 1.0 - zeroRow = False - if zeroRow: - raise RuntimeError("Jacobian has a zero row because sparse matrix has no diagonal entry at row "+repr(global_dofN)+". You probably need add diagonal mass or reaction term") - #scaling = 1.0#probably want to add some scaling to match non-dirichlet diagonals in linear system - #for cj in range(self.nc): - # for dofN in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.keys()): - # global_dofN = self.offset[cj]+self.stride[cj]*dofN - # for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]): - # if (self.colind[i] == global_dofN): - # self.nzval[i] = scaling - # else: - # self.nzval[i] = 0.0 - logEvent("Jacobian ",level=10,data=jacobian) - #mwf decide if this is reasonable for solver statistics - self.nonlinear_function_jacobian_evaluations += 1 - return jacobian - def calculateElementQuadrature(self): - """ - Calculate the physical location and weights of the quadrature rules - and the shape information at the quadrature points. - - This function should be called only when the mesh changes. - """ - #self.u[0].femSpace.elementMaps.getValues(self.elementQuadraturePoints, - # self.q['x']) - self.u[0].femSpace.elementMaps.getBasisValuesRef(self.elementQuadraturePoints) - self.u[0].femSpace.elementMaps.getBasisGradientValuesRef(self.elementQuadraturePoints) - self.u[0].femSpace.getBasisValuesRef(self.elementQuadraturePoints) - self.u[0].femSpace.getBasisGradientValuesRef(self.elementQuadraturePoints) - self.coefficients.initializeElementQuadrature(self.timeIntegration.t,self.q) - if self.stabilization != None: - self.stabilization.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) - self.stabilization.initializeTimeIntegration(self.timeIntegration) - if self.shockCapturing != None: - self.shockCapturing.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) - def calculateElementBoundaryQuadrature(self): - pass - def calculateExteriorElementBoundaryQuadrature(self): - """ - Calculate the physical location and weights of the quadrature rules - and the shape information at the quadrature points on global element boundaries. - - This function should be called only when the mesh changes. - """ - # - #get physical locations of element boundary quadrature points - # - #assume all components live on the same mesh - self.u[0].femSpace.elementMaps.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.elementMaps.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.elementMaps.getValuesGlobalExteriorTrace(self.elementBoundaryQuadraturePoints, - self.ebqe['x']) - self.fluxBoundaryConditionsObjectsDict = dict([(cj,FluxBoundaryConditions(self.mesh, - self.nElementBoundaryQuadraturePoints_elementBoundary, - self.ebqe[('x')], - getAdvectiveFluxBoundaryConditions=self.advectiveFluxBoundaryConditionsSetterDict[cj], - getDiffusiveFluxBoundaryConditions=self.diffusiveFluxBoundaryConditionsSetterDictDict[cj])) - for cj in list(self.advectiveFluxBoundaryConditionsSetterDict.keys())]) - self.coefficients.initializeGlobalExteriorElementBoundaryQuadrature(self.timeIntegration.t,self.ebqe) - def estimate_mt(self): - pass - def calculateSolutionAtQuadrature(self): - pass - def calculateAuxiliaryQuantitiesAfterStep(self): - pass \ No newline at end of file diff --git a/richards_fct/richards/edit/Richards_corrupted.h b/richards_fct/richards/edit/Richards_corrupted.h deleted file mode 100644 index 36a10ac428..0000000000 --- a/richards_fct/richards/edit/Richards_corrupted.h +++ /dev/null @@ -1,3205 +0,0 @@ -#ifndef Richards_H -#define Richards_H -#include -#include -#include -#include "CompKernel.h" -#include "ModelFactory.h" -#include "../mprans/ArgumentsDict.h" -#include "xtensor-python/pyarray.hpp" -#define nnz nSpace - -namespace py = pybind11; -#define POWER_SMOOTHNESS_INDICATOR 2 -#define IS_BETAij_ONE 0 -#define GLOBAL_FCT 0 -namespace proteus -{ - // Power entropy // - inline double ENTROPY(const double& phi, const double& phiL, const double& phiR){ - return 1./2.*std::pow(fabs(phi),2.); - } - inline double DENTROPY(const double& phi, const double& phiL, const double& phiR){ - return fabs(phi)*(phi>=0 ? 1 : -1); - } - // Log entropy // for level set from 0 to 1 - inline double ENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ - return std::log(fabs((phi-phiL)*(phiR-phi))+1E-14); - } - inline double DENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ - return (phiL+phiR-2*phi)*((phi-phiL)*(phiR-phi)>=0 ? 1 : -1)/(fabs((phi-phiL)*(phiR-phi))+1E-14); - } -} - -namespace proteus - -{ - class Richards_base - { - //The base class defining the interface - public: - virtual ~Richards_base(){ - double anb_seepage_flux =1e-16; - } - virtual void calculateResidual(arguments_dict& args)=0; - virtual void calculateJacobian(arguments_dict& args)=0; - virtual void invert(arguments_dict& args)=0; - virtual void FCTStep(arguments_dict& args)=0; - virtual void kth_FCT_step(arguments_dict& args)=0; - virtual void calculateResidual_entropy_viscosity(arguments_dict& args)=0; - virtual void calculateMassMatrix(arguments_dict& args)=0; - }; - - template - class Richards : public Richards_base - { - public: - const int nDOF_test_X_trial_element; - CompKernelType ck; - Richards(): - nDOF_test_X_trial_element(nDOF_test_element*nDOF_trial_element), - ck() - {} - inline - void evaluateCoefficients(const int rowptr[nSpace], - const int colind[nnz], - const double rho, - const double beta, - const double gravity[nSpace], - const double alpha, - const double n_vg, - const double thetaR, - const double thetaSR, - const double KWs[nnz], - const double& u, - double& m, - double& dm, - double f[nSpace], - double df[nSpace], - double a[nnz], - double da[nnz], - double as[nnz], - double& kr, - double& dkr) - { - const int nSpace2 = nSpace * nSpace; - double psiC; - double pcBar; - double pcBar_n; - double pcBar_nM1; - double pcBar_nM2; - double onePlus_pcBar_n; - double sBar; - double sqrt_sBar; - double DsBar_DpsiC; - double thetaW; - double DthetaW_DpsiC; - double vBar; - double vBar2; - double DvBar_DpsiC; - double KWr; - double DKWr_DpsiC; - double rho2 = rho * rho; - double thetaS; - double rhom; - double drhom; - double m_vg; - double pcBarStar; - double sqrt_sBarStar; - - psiC = -u; - m_vg = 1.0 - 1.0 / n_vg; - thetaS = thetaR + thetaSR; - //std::cout<< "Thetas"< 0.0) - { - pcBar = alpha * psiC; - pcBarStar = pcBar; - if (pcBar < 1.0e-8) - pcBarStar = 1.0e-8; - pcBar_nM2 = pow(pcBarStar, n_vg - 2); - pcBar_nM1 = pcBar_nM2 * pcBar; - pcBar_n = pcBar_nM1 * pcBar; - onePlus_pcBar_n = 1.0 + pcBar_n; - - sBar = pow(onePlus_pcBar_n, -m_vg); - /* using -mn = 1-n */ - DsBar_DpsiC = alpha * (1.0 - n_vg) * (sBar/onePlus_pcBar_n)*pcBar_nM1; - - vBar = 1.0-pcBar_nM1*sBar; - vBar2 = vBar*vBar; - DvBar_DpsiC = -alpha*(n_vg-1.0)*pcBar_nM2*sBar - pcBar_nM1*DsBar_DpsiC; - - thetaW = thetaSR*sBar + thetaR; - DthetaW_DpsiC = thetaSR * DsBar_DpsiC; - - sqrt_sBar = sqrt(sBar); - sqrt_sBarStar = sqrt_sBar; - if (sqrt_sBar < 1.0e-8) - sqrt_sBarStar = 1.0e-8; - KWr= sqrt_sBar*vBar2; - DKWr_DpsiC= ((0.5/sqrt_sBarStar)*DsBar_DpsiC*vBar2 - + - 2.0*sqrt_sBar*vBar*DvBar_DpsiC); - } - else - { - thetaW = thetaS; - DthetaW_DpsiC = 0.0; - KWr = 1.0; - DKWr_DpsiC = 0.0; - } - //slight compressibility - rhom = rho*exp(beta*u); - drhom = beta*rhom; - m = rhom*thetaW; - dm = -rhom*DthetaW_DpsiC+drhom*thetaW; - for (int I=0;I thetaS || thetaW <= thetaR) - { - //cek debug - std::cout<<"rho "< 0.0) - { - isDOFBoundary = 1; - bc_u = bc_u_seepage; - } - else - { - isDOFBoundary = 0; - flux = 0.0; - } - } - /* //set DOF flag and flux correctly if seepage face */ - /* if (isSeepageFace) */ - /* { */ - /* if (flux < 0.0 || u < bc_u_seepage) */ - /* { */ - /* isDOFBoundary = 0; */ - /* flux = 0.0; */ - /* } */ - /* else */ - /* { */ - /* isDOFBoundary = 1; */ - /* bc_u = bc_u_seepage; */ - /* } */ - /* } */ - /* //Dirichlet penalty */ - /* if (isDOFBoundary) */ - /* flux += penalty*(u-bc_u); */ - } - else - flux = bc_flux; - } - - void exteriorNumericalFluxJacobian(const int rowptr[nSpace], - const int colind[nnz], - const int isDOFBoundary, - const double n[nSpace], - const double K[nnz], - const double dK[nnz], - const double grad_psi[nSpace], - const double grad_v[nSpace], - const double dK_rho_g[nSpace], - const double v, - const double penalty, - double& fluxJacobian) - { - if (isDOFBoundary) - { - fluxJacobian = 0.0; - for(int I=0;I& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - double sc_uref = args.scalar("sc_uref"); - double sc_alpha = args.scalar("sc_alpha"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& u_dof_old = args.array("u_dof_old"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m = args.array("q_m"); - xt::pyarray& q_u = args.array("q_u"); - xt::pyarray& q_dV = args.array("q_dV"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - int offset_u = args.scalar("offset_u"); - int stride_u = args.scalar("stride_u"); - xt::pyarray& globalResidual = args.array("globalResidual"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& ebqe_phi = args.array("ebqe_phi"); - double epsFact = args.scalar("epsFact"); - xt::pyarray& ebqe_u = args.array("ebqe_u"); - xt::pyarray& ebqe_flux = args.array("ebqe_flux"); - // PARAMETERS FOR EDGE BASED STABILIZATION - double cE = args.scalar("cE"); - double cK = args.scalar("cK"); - // PARAMETERS FOR LOG BASED ENTROPY FUNCTION - double uL = args.scalar("uL"); - double uR = args.scalar("uR"); - // PARAMETERS FOR EDGE VISCOSITY - int numDOFs = args.scalar("numDOFs"); - int NNZ = args.scalar("NNZ"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); - xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); - xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); - xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); - // C matrices - xt::pyarray& Cx = args.array("Cx"); - xt::pyarray& Cy = args.array("Cy"); - xt::pyarray& Cz = args.array("Cz"); - xt::pyarray& CTx = args.array("CTx"); - xt::pyarray& CTy = args.array("CTy"); - xt::pyarray& CTz = args.array("CTz"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); - int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); - // FOR FCT - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& fluxMatrix = args.array("fluxMatrix"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); - xt::pyarray& min_s_bc = args.array("min_s_bc"); - xt::pyarray& max_s_bc = args.array("max_s_bc"); - // AUX QUANTITIES OF INTEREST - xt::pyarray& quantDOFs = args.array("quantDOFs"); - xt::pyarray& sLow = args.array("sLow"); - xt::pyarray& sn = args.array("sn"); - - assert(a_rowptr.data()[nSpace] == nnz); - assert(a_rowptr.data()[nSpace] == nSpace); - //cek should this be read in? - double Ct_sge = 4.0; - //For flux Calculation - //double anb_seepage_flux=0.0; - //anb_seepage_flux = args["anb_seepage_flux"]; - //double anb_seepage_flux = args.scalar("anb_seepage_flux"); - //anb_seepage_flux=0.0; - - xt::pyarray& anb_seepage_flux_n = args.array("anb_seepage_flux_n"); - - - //double anb_seepage_flux=0.0; - double & anb_seepage_flux (args.scalar("anb_seepage_flux")) ; - //double anb_seepage_flux = args.scalar("anb_seepage_flux_n"); - - //double anb_seepage_flux=0.0; - anb_seepage_flux=0.0; - - //loop over elements to compute volume integrals and load them into element and global residual - // - //eN is the element index - //eN_k is the quadrature point index for a scalar - //eN_k_nSpace is the quadrature point index for a vector - //eN_i is the element test function index - //eN_j is the element trial function index - //eN_k_j is the quadrature point index for a trial function - //eN_k_i is the quadrature point index for a trial function - for(int eN=0;eN0) - { - std::cout<<"The seepage flux is "<& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); - xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); - xt::pyarray& globalJacobian = args.array("globalJacobian"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - assert(a_rowptr.data()[nSpace] == nnz); - assert(a_rowptr.data()[nSpace] == nSpace); - double Ct_sge = 4.0; - - - // - //loop over elements to compute volume integrals and load them into the element Jacobians and global Jacobian - // - for(int eN=0;eN& bc_mask = args.array("bc_mask"); - int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern - int numDOFs = args.scalar("numDOFs"); //number of DOFs - double dt = args.scalar("dt"); - xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) - xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn - xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn - xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& limited_solution = args.array("limited_solution"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets - xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices - xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 - xt::pyarray& max_s_bc = args.array("max_s_bc"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int MONOLITHIC = args.scalar("MONOLITHIC"); - register double Rpos[numDOFs], Rneg[numDOFs]; - register double FluxCorrectionMatrix[NNZ]; - register double solL[numDOFs]; - register double sdot[numDOFs]; - ////////////////// - // LOOP in DOFs // - ////////////////// - int ij=0; - for (int i=0; i 0) ? 1. : 0.); - Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); - - //update ij - ij+=1; - //std::cout<<"sdoti error"<0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])) - * FluxCorrectionMatrix[ij]; - alpha_dot = fmin(1.0, beta_ij*fabs(alpha_fA)/MassMatrix.data()[ij]/fmax(1.0e-8,fabs(sdoti-sdotj))); - if (MONOLITHIC == 0) - { - ith_Limiter_times_FluxCorrectionMatrix += alpha_fA; - } - else - { - ith_Limiter_times_FluxCorrectionMatrix += alpha_fA + (LUMPED_MASS_MATRIX == 1 ? 0. : 1.)*dt*alpha_dot*MassMatrix.data()[ij]*(sdoti-sdotj); - } - //update ij - ij+=1; - } - limited_solution.data()[i] = solL[i] + 1./lumped_mass_matrix.data()[i]*ith_Limiter_times_FluxCorrectionMatrix*bc_mask[i]; - } - } - - void kth_FCT_step(arguments_dict& args) - { - int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern - int numDOFs = args.scalar("numDOFs"); //number of DOFs - int num_fct_iter = args.scalar("num_fct_iter"); - double dt = args.scalar("dt"); - xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) - xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn - xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn - xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& solLim = args.array("limited_solution"); - xt::pyarray& MC = args.array("MC"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& FluxMatrix = args.array("FluxMatrix"); - xt::pyarray& limitedFlux = args.array("limited_Flux"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets - xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices - xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 - xt::pyarray& max_s_bc = args.array("max_s_bc"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int MONOLITHIC = args.scalar("MONOLITHIC"); - register double Rpos[numDOFs], Rneg[numDOFs]; - int ij=0; - - ////////////////////////////////////////////////////// - // ********** COMPUTE LOW ORDER SOLUTION ********** // - ////////////////////////////////////////////////////// - if (num_fct_iter == 0) - { // No FCT for global bounds - for (int i=0; i 0) ? 1. : 0.); - // update ij - ij+=1; - } - // compute Q vectors - double mi = ML.data()[i]; - double solLimi = solLim.data()[i]; - double Qposi = mi*(maxi-solLimi); - // compute R vectors - Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - } - ij=0; - for (int i=0; i0 ? Rposi : Rpos[j]); - // compute limited flux - ith_Limiter_times_FluxCorrectionMatrix += Lij*Fluxij; - - // update limited flux - limitedFlux.data()[ij] = Lij*Fluxij; - - //update FluxMatrix - FluxMatrix.data()[ij] = Fluxij; - - //update ij - ij+=1; - } - //update limited solution - double mi = ML.data()[i]; - solLim.data()[i] += 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; - } - } - } - - // ***************************************** // - // ********** HIGH ORDER SOLUTION ********** // - // ***************************************** // - ij=0; - for (int i=0; i 0 ? 1. : 0.); - Pnegi += fij * (fij < 0 ? 1. : 0.); - //update ij - ij+=1; - } - // compute Q vectors // - double mi = ML.data()[i]; - double Qposi = mi*(maxi-solLim.data()[i]); - double Qnegi = mi*(mini-solLim.data()[i]); - // compute R vectors // - Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); - } - - // COMPUTE LIMITERS // - ij=0; - for (int i=0; i 0 ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j]); - // compute ith_limited_flux_correction - ith_limited_flux_correction += Lij*fij; - ij+=1; - } - double mi = ML.data()[i]; - solLim[i] += 1./mi*ith_limited_flux_correction; - } - } - - void calculateResidual_entropy_viscosity(arguments_dict& args) - { - xt::pyarray& globalJacobian = args.array("globalJacobian"); - double Theta = args.scalar("Theta"); - xt::pyarray& bc_mask = args.array("bc_mask"); - double dt = args.scalar("dt"); - xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - double sc_uref = args.scalar("sc_uref"); - double sc_alpha = args.scalar("sc_alpha"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& r_l2g = args.array("r_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - int degree_polynomial = args.scalar("degree_polynomial"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& u_dof_old = args.array("u_dof_old"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m = args.array("q_m"); - xt::pyarray& q_u = args.array("q_u"); - xt::pyarray& q_dV = args.array("q_dV"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - int offset_u = args.scalar("offset_u"); - int stride_u = args.scalar("stride_u"); - xt::pyarray& globalResidual = args.array("globalResidual"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& ebqe_phi = args.array("ebqe_phi"); - double epsFact = args.scalar("epsFact"); - xt::pyarray& ebqe_u = args.array("ebqe_u"); - xt::pyarray& ebqe_flux = args.array("ebqe_flux"); - // PARAMETERS FOR EDGE BASED STABILIZATION - double cE = args.scalar("cE"); - double cK = args.scalar("cK"); - // PARAMETERS FOR LOG BASED ENTROPY FUNCTION - double uL = args.scalar("uL"); - double uR = args.scalar("uR"); - // PARAMETERS FOR EDGE VISCOSITY - int numDOFs = args.scalar("numDOFs"); - int NNZ = args.scalar("NNZ"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); - xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); - xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); - xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); - // C matrices - xt::pyarray& Cx = args.array("Cx"); - xt::pyarray& Cy = args.array("Cy"); - xt::pyarray& Cz = args.array("Cz"); - xt::pyarray& CTx = args.array("CTx"); - xt::pyarray& CTy = args.array("CTy"); - xt::pyarray& CTz = args.array("CTz"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); - int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); - // FOR FCT - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& fluxMatrix = args.array("fluxMatrix"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); - xt::pyarray& min_s_bc = args.array("min_s_bc"); - xt::pyarray& max_s_bc = args.array("max_s_bc"); - // AUX QUANTITIES OF INTEREST - xt::pyarray& quantDOFs = args.array("quantDOFs"); - xt::pyarray& sLow = args.array("sLow"); - xt::pyarray& sn = args.array("sn"); - - xt::pyarray& anb_seepage_flux_n = args.array("anb_seepage_flux_n"); - - - //double anb_seepage_flux=0.0; - double & anb_seepage_flux (args.scalar("anb_seepage_flux")) ; - //double anb_seepage_flux = args.scalar("anb_seepage_flux_n"); - - //double anb_seepage_flux=0.0; - anb_seepage_flux=0.0; - - - register double Rpos[numDOFs], Rneg[numDOFs]; - //register double FluxCorrectionMatrix[NNZ]; - // NOTE: This function follows a different (but equivalent) implementation of the smoothness based indicator than NCLS.h - // Allocate space for the transport matrices - // This is used for first order KUZMIN'S METHOD - register double TransportMatrix[NNZ],TransportMatrixConsistent[NNZ]; - register double TransportMatrixn[NNZ],TransportMatrixConsistentn[NNZ]; - std::valarray u_free_dof(numDOFs); - std::valarray u_free_dof_old(numDOFs); - std::valarray ML2(numDOFs); - - - for(int eN=0;eN0) - { - std::cout<<"The seepage flux is "<("anb_seepage_flux_n"); - //anb_seepage_flux_n=0.0; - - //anb_seepage_flux_n= anb_seepage_flux; - - - - //if (isSeepageFace) - //{ - // anb_seepage_flux+= dS* flux_ext; - // std::cout<<"The seepage flux is "<0){ - // std::cout<<"The seepage flux is "<= 0 && isFluxBoundary_u[ebNE_kb] != 1 ) //outflow. This is handled via the transport matrices. Then flux_ext=0 and dflux_ext!=0 - // { - // dflux_ext = flow; - // flux_ext = 0; - // // save external u - // ebqe_u[ebNE_kb] = u_ext; - // } - //else // inflow. This is handled via the boundary integral. Then flux_ext!=0 and dflux_ext=0 - //{ - //dflux_ext = 0; - // save external u - //ebqe_u[ebNE_kb] = isDOFBoundary_u[ebNE_kb]*ebqe_bc_u_ext[ebNE_kb]+(1-isDOFBoundary_u[ebNE_kb])*u_ext; - //if (isDOFBoundary_u[ebNE_kb] == 1) - // flux_ext = ebqe_bc_u_ext[ebNE_kb]*flow; - //else if (isFluxBoundary_u[ebNE_kb] == 1) - //flux_ext = ebqe_bc_flux_u_ext[ebNE_kb]; - // flux_ext = ebqe_bc_u_ext[ebNE_kb]; - //else - // { - // std::cout<<"warning: VOF open boundary with no external trace, setting to zero for inflow"<= 0.) - { - alpha_numerator_pos += alpha_num; - alpha_denominator_pos += alpha_num; - } - else - { - alpha_numerator_neg += alpha_num; - alpha_denominator_neg += fabs(alpha_num); - } - //update ij - ij+=1; - } - // scale g vector by lumped mass matrix - if (fabs(ML.data()[i] - ML2[i]) > 1.0e-16) - std::cout<<"ML "< 0.0) - // assert( (xi[I] - xj[I]) == delta_x_ij[offset*3+I]); - //gi_times_x += gi[I]*(xi[I]-xj[I]); - gi_times_x += gi[I]*delta_x_ij.data()[offset*3+I]; - } - // compute the positive and negative part of gi*(xi-xj) - SumPos += gi_times_x > 0 ? gi_times_x : 0; - SumNeg += gi_times_x < 0 ? gi_times_x : 0; - } - double sigmaPosi = fmin(1.,(fabs(SumNeg)+1E-15)/(SumPos+1E-15)); - double sigmaNegi = fmin(1.,(SumPos+1E-15)/(fabs(SumNeg)+1E-15)); - double alpha_numi = fabs(sigmaPosi*alpha_numerator_pos + sigmaNegi*alpha_numerator_neg); - double alpha_deni = sigmaPosi*alpha_denominator_pos + sigmaNegi*alpha_denominator_neg; - if (IS_BETAij_ONE == 1) - { - alpha_numi = fabs(alpha_numerator_pos + alpha_numerator_neg); - alpha_deni = alpha_denominator_pos + alpha_denominator_neg; - } - double alphai = alpha_numi/(alpha_deni+1E-15); - quantDOFs.data()[i] = alphai; - - if (POWER_SMOOTHNESS_INDICATOR==0) - psi[i] = 1.0; - else - psi[i] = std::pow(alphai,POWER_SMOOTHNESS_INDICATOR); //NOTE: they use alpha^2 in the paper - } - ///////////////////////////////////////////// - // ** LOOP IN DOFs FOR EDGE BASED TERMS ** // - ///////////////////////////////////////////// - ij=0; - for (int i=0; i Dissipation matrices as well. - double soli = u_free_dof[i]; // solution at time tn for the ith DOF - double solni = u_free_dof_old[i]; // solution at time tn for the ith DOF - for (int I=0;I mMax) - { - std::cout<<"mass out of bounds "< 0) ? 1. : 0.); - // Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); - // ij+=1; - // } - // double mi = ML[i]; - // double solni = u_dof_old[i]; - // double Qposi = mi*(maxi-solni); - // double Qnegi = mi*(mini-solni); - - //std::cout << Qposi << std::endl; - // Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - // Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); - - //if (Rpos[i] < 0) - //{ - // std::cout << mi << "\t" << maxi << "\t" << solni << std::endl; - // std::cout << Qposi << "\t" << Pposi << std::endl; - // std::cout << Rpos[i] << std::endl; - //abort(); - //} - //} - - //ij=0; - //for (int i=0; i 1.0 || Rposi < 0.0) - //std::cout << "Rposi: " << Rposi << std::endl; - //if (Rnegi > 1.0 || Rnegi < 0.0) - //std::cout << "Rnegi: " << Rnegi << std::endl; - - // LOOP OVER THE SPARSITY PATTERN (j-LOOP)// - // for (int offset=csrRowIndeces_DofLoops.data()[i]; - // offset0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])); - // //Lij=0.0; - // ith_Limiter_times_FluxCorrectionMatrix += Lij*FluxCorrectionMatrix[ij]; - // //update ij - // ij+=1; - // } - // double mi = ML[i]; - // double solni = u_dof_old[i]; - // globalResidual[i] = solni + 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; - //} - } - - - void invert(arguments_dict& args) - { - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - xt::pyarray& globalResidual = args.array("globalResidual"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - int numDOFs = args.scalar("numDOFs"); - for (int i=0; i mMax) - { - std::cout<<"mass out of bounds "<("dt"); - xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - //element boundary - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - //physics - int nElements_global = args.scalar("nElements_global"); - //new - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - //end new - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& r_l2g = args.array("r_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - int degree_polynomial = args.scalar("degree_polynomial"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); - xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); - xt::pyarray& globalJacobian = args.array("globalJacobian"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - //std::cout<<"ndjaco address "<(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - else if (nSpaceIn == 2) - return proteus::chooseAndAllocateDiscretization2D(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - else - { - assert(nSpaceIn == 3); - return proteus::chooseAndAllocateDiscretization(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - } - } -};//proteus -#endif \ No newline at end of file diff --git a/richards_fct/richards/edit/Richards_corrupted.py b/richards_fct/richards/edit/Richards_corrupted.py deleted file mode 100644 index 7199b31595..0000000000 --- a/richards_fct/richards/edit/Richards_corrupted.py +++ /dev/null @@ -1,1848 +0,0 @@ -from __future__ import division -from builtins import range -from past.utils import old_div -import proteus -from .cRichards import * -import numpy as np -from proteus.Transport import OneLevelTransport -from proteus.Transport import TC_base, NonlinearEquation, logEvent, memory -from proteus.Transport import FluxBoundaryConditions, Comm, cfemIntegrals -from proteus.Transport import DOFBoundaryConditions, Quadrature -from proteus.mprans import cArgumentsDict -from proteus.LinearAlgebraTools import SparseMat -from proteus import TimeIntegration -from proteus.NonlinearSolvers import ExplicitLumpedMassMatrixForRichards - -class ThetaScheme(TimeIntegration.BackwardEuler): - def __init__(self,transport,integrateInterpolationPoints=False): - self.transport=transport - TimeIntegration.BackwardEuler.__init__(self,transport, integrateInterpolationPoints) - def updateTimeHistory(self,resetFromDOF=False): - TimeIntegration.BackwardEuler.updateTimeHistory(self,resetFromDOF) - self.transport.u_dof_old[:] = self.u -class RKEV(TimeIntegration.SSP): - from proteus import TimeIntegration - """ - Wrapper for SSPRK time integration using EV - - ... more to come ... - """ - - def __init__(self, transport, timeOrder=1, runCFL=0.1, integrateInterpolationPoints=False): - TimeIntegration.SSP.__init__(self, transport, integrateInterpolationPoints=integrateInterpolationPoints) - self.runCFL = runCFL - self.dtLast = None - self.isAdaptive = True - # About the cfl - assert transport.coefficients.STABILIZATION_TYPE > 0, "SSP method just works for edge based EV methods; i.e., STABILIZATION_TYPE>0" - assert hasattr(transport, 'edge_based_cfl'), "No edge based cfl defined" - self.cfl = transport.edge_based_cfl - # Stuff particular for SSP - self.timeOrder = timeOrder # order of approximation - self.nStages = timeOrder # number of stages total - self.lstage = 0 # last stage completed - # storage vectors - self.u_dof_last = {} - # per component stage values, list with array at each stage - self.u_dof_stage = {} - for ci in range(self.nc): - if ('m', ci) in transport.q: - self.u_dof_last[ci] = transport.u[ci].dof.copy() - self.u_dof_stage[ci] = [] - for k in range(self.nStages + 1): - self.u_dof_stage[ci].append(transport.u[ci].dof.copy()) - #print() - - - # def set_dt(self, DTSET): - # self.dt = DTSET # don't update t - def choose_dt(self): - comm = Comm.get() - maxCFL = 1.0e-6 - maxCFL = max(maxCFL, comm.globalMax(self.cfl.max())) - self.dt = old_div(self.runCFL, maxCFL) - if self.dtLast is None: - self.dtLast = self.dt - self.t = self.tLast + self.dt - self.substeps = [self.t for i in range(self.nStages)] # Manuel is ignoring different time step levels for now - #print("Hi, This is Arnob") - - - def initialize_dt(self, t0, tOut, q): - """ - Modify self.dt - """ - self.tLast = t0 - self.choose_dt() - self.t = t0 + self.dt - - def setCoefficients(self): - """ - beta are all 1's here - mwf not used right now - """ - self.alpha = np.zeros((self.nStages, self.nStages), 'd') - self.dcoefs = np.zeros((self.nStages), 'd') - - def updateStage(self): - """ - Need to switch to use coefficients - """ - self.lstage += 1 - assert self.timeOrder in [1, 2, 3] - assert self.lstage > 0 and self.lstage <= self.timeOrder - if self.timeOrder == 3: - if self.lstage == 1: - logEvent("First stage of SSP33 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - # update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] - elif self.lstage == 2: - logEvent("Second stage of SSP33 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - self.u_dof_stage[ci][self.lstage] *= old_div(1., 4.) - self.u_dof_stage[ci][self.lstage] += 3. / 4. * self.u_dof_last[ci] - # Update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] - elif self.lstage == 3: - logEvent("Third stage of SSP33 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - self.u_dof_stage[ci][self.lstage] *= old_div(2.0, 3.0) - self.u_dof_stage[ci][self.lstage] += 1.0 / 3.0 * self.u_dof_last[ci] - # update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_last[ci] - # update solution to u[0].dof - self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] - elif self.timeOrder == 2: - if self.lstage == 1: - logEvent("First stage of SSP22 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - # Update u_dof_old - self.transport.u_dof_old[:] = self.transport.u[ci].dof - elif self.lstage == 2: - logEvent("Second stage of SSP22 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - self.u_dof_stage[ci][self.lstage][:] *= old_div(1., 2.) - self.u_dof_stage[ci][self.lstage][:] += 1. / 2. * self.u_dof_last[ci] - # update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_last[ci] - # update solution to u[0].dof - self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] - else: - assert self.timeOrder == 1 - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof[:] - self.transport.u_dof_old[:] = self.transport.u[ci].dof - #self.print("Hi, Arnob") - - def initializeTimeHistory(self, resetFromDOF=True): - """ - Push necessary information into time history arrays - """ - for ci in range(self.nc): - self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] - for k in range(self.nStages): - self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] - - def updateTimeHistory(self, resetFromDOF=False): - """ - assumes successful step has been taken - """ - - self.t = self.tLast + self.dt - for ci in range(self.nc): - self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] - for k in range(self.nStages): - self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] - self.lstage = 0 - self.dtLast = self.dt - self.tLast = self.t - - def generateSubsteps(self, tList): - """ - create list of substeps over time values given in tList. These correspond to stages - """ - self.substeps = [] - tLast = self.tLast - for t in tList: - dttmp = t - tLast - self.substeps.extend([tLast + dttmp for i in range(self.nStages)]) - tLast = t - - def resetOrder(self, order): - """ - initialize data structures for stage updges - """ - self.timeOrder = order # order of approximation - self.nStages = order # number of stages total - self.lstage = 0 # last stage completed - # storage vectors - # per component stage values, list with array at each stage - self.u_dof_stage = {} - for ci in range(self.nc): - if ('m', ci) in self.transport.q: - self.u_dof_stage[ci] = [] - for k in range(self.nStages + 1): - self.u_dof_stage[ci].append(self.transport.u[ci].dof.copy()) - self.substeps = [self.t for i in range(self.nStages)] - - def setFromOptions(self, nOptions): - """ - allow classes to set various numerical parameters - """ - if 'runCFL' in dir(nOptions): - self.runCFL = nOptions.runCFL - flags = ['timeOrder'] - for flag in flags: - if flag in dir(nOptions): - val = getattr(nOptions, flag) - setattr(self, flag, val) - if flag == 'timeOrder': - self.resetOrder(self.timeOrder) - - - -class Coefficients(proteus.TransportCoefficients.TC_base): - """ - version of Re where element material type id's used in evals - """ - from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2 - from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchten_sd_het - def __init__(self, - nd, - Ksw_types, - vgm_n_types, - vgm_alpha_types, - thetaR_types, - thetaSR_types, - gravity, - density, - beta, - diagonal_conductivity=True, - getSeepageFace=None, - # FOR EDGE BASED EV - STABILIZATION_TYPE=0, - ENTROPY_TYPE=2, # logarithmic - LUMPED_MASS_MATRIX=False, - MONOLITHIC=True, - FCT=True, - num_fct_iter=1, - # FOR ENTROPY VISCOSITY - cE=1.0, - uL=0.0, - uR=1.0, - # FOR ARTIFICIAL COMPRESSION - cK=1.0, - # OUTPUT quantDOFs - outputQuantDOFs=False, ): - self.anb_seepage_flux= 0.00 - #self.anb_seepage_flux_n =0.0 - variableNames=['pressure_head'] - nc=1 - mass={0:{0:'nonlinear'}} - advection={0:{0:'nonlinear'}} - diffusion={0:{0:{0:'nonlinear'}}} - potential={0:{0:'u'}} - reaction={0:{0:'linear'}} - hamiltonian={} - self.getSeepageFace=getSeepageFace - self.gravity=gravity - self.rho = density - self.beta=beta - self.vgm_n_types = vgm_n_types - self.vgm_alpha_types = vgm_alpha_types - self.thetaR_types = thetaR_types - self.thetaSR_types = thetaSR_types - self.elementMaterialTypes = None - self.exteriorElementBoundaryTypes = None - self.materialTypes_q = None - self.materialTypes_ebq = None - self.materialTypes_ebqe = None - self.nd = nd - self.nMaterialTypes = len(thetaR_types) - self.q = {}; self.ebqe = {}; self.ebq = {}; self.ebq_global={} - #try to allow some flexibility in input of permeability/conductivity tensor - self.diagonal_conductivity = diagonal_conductivity - self.Ksw_types_in = Ksw_types - if self.diagonal_conductivity: - sparseDiffusionTensors = {(0,0):(np.arange(self.nd+1,dtype='i'), - np.arange(self.nd,dtype='i'))} - - assert len(Ksw_types.shape) in [1,2], "if diagonal conductivity true then Ksw_types scalar or vector of diagonal entries" - #allow scalar input Ks - if len(Ksw_types.shape)==1: - self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd),'d') - for I in range(self.nd): - self.Ksw_types[:,I] = Ksw_types - else: - self.Ksw_types = Ksw_types - else: #full - sparseDiffusionTensors = {(0,0):(np.arange(self.nd**2+1,step=self.nd,dtype='i'), - np.array([list(range(self.nd)) for row in range(self.nd)],dtype='i'))} - assert len(Ksw_types.shape) in [1,2], "if full tensor conductivity true then Ksw_types scalar or 'flattened' row-major representation of entries" - if len(Ksw_types.shape)==1: - self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd**2),'d') - for I in range(self.nd): - self.Ksw_types[:,I*self.nd+I] = Ksw_types - else: - assert Ksw_types.shape[1] == self.nd**2 - self.Ksw_types = Ksw_types - # EDGE BASED (AND ENTROPY) VISCOSITY - self.LUMPED_MASS_MATRIX = LUMPED_MASS_MATRIX - self.MONOLITHIC = MONOLITHIC - self.STABILIZATION_TYPE = STABILIZATION_TYPE - self.ENTROPY_TYPE = ENTROPY_TYPE - self.FCT = FCT - self.num_fct_iter=num_fct_iter - self.uL = uL - self.uR = uR - self.cK = cK - self.forceStrongConditions = True - self.cE = cE - self.outputQuantDOFs = outputQuantDOFs - TC_base.__init__(self, - nc, - mass, - advection, - diffusion, - potential, - reaction, - hamiltonian, - variableNames, - sparseDiffusionTensors = sparseDiffusionTensors, - useSparseDiffusion = True) - - def initializeMesh(self,mesh): - from proteus.SubsurfaceTransportCoefficients import BlockHeterogeneousCoefficients - self.elementMaterialTypes,self.exteriorElementBoundaryTypes,self.elementBoundaryTypes = BlockHeterogeneousCoefficients(mesh).initializeMaterialTypes() - #want element boundary material types for evaluating heterogeneity - #not boundary conditions - self.isSeepageFace = np.zeros((mesh.nExteriorElementBoundaries_global),'i') - if self.getSeepageFace != None: - for ebNE in range(mesh.nExteriorElementBoundaries_global): - #mwf missing ebNE-->ebN? - ebN = mesh.exteriorElementBoundariesArray[ebNE] - #print "eb flag",mesh.elementBoundaryMaterialTypes[ebN] - #print("Hi, Arnob") - #print self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) - self.isSeepageFace[ebNE] = self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) - #print (self.isSeepageFace) - def initializeElementQuadrature(self,t,cq): - self.materialTypes_q = self.elementMaterialTypes - self.q_shape = cq[('u',0)].shape - #self.anb_seepage_flux= anb_seepage_flux - #print("The seepage is ", anb_seepage_flux) -# cq['Ks'] = np.zeros(self.q_shape,'d') -# for k in range(self.q_shape[1]): -# cq['Ks'][:,k] = self.Ksw_types[self.elementMaterialTypes,0] - self.q[('vol_frac',0)] = np.zeros(self.q_shape,'d') - def initializeElementBoundaryQuadrature(self,t,cebq,cebq_global): - self.materialTypes_ebq = np.zeros(cebq[('u',0)].shape[0:2],'i') - self.ebq_shape = cebq[('u',0)].shape - for ebN_local in range(self.ebq_shape[1]): - self.materialTypes_ebq[:,ebN_local] = self.elementMaterialTypes - self.ebq[('vol_frac',0)] = np.zeros(self.ebq_shape,'d') - - def initializeGlobalExteriorElementBoundaryQuadrature(self,t,cebqe): - self.materialTypes_ebqe = self.exteriorElementBoundaryTypes - self.ebqe_shape = cebqe[('u',0)].shape - self.ebqe[('vol_frac',0)] = np.zeros(self.ebqe_shape,'d') - # - - - def evaluate(self,t,c): - if c[('u',0)].shape == self.q_shape: - materialTypes = self.materialTypes_q - vol_frac = self.q[('vol_frac',0)] - elif c[('u',0)].shape == self.ebqe_shape: - materialTypes = self.materialTypes_ebqe - vol_frac = self.ebqe[('vol_frac',0)] - elif c[('u',0)].shape == self.ebq_shape: - materialTypes = self.materialTypes_ebq - vol_frac = self.ebq[('vol_frac',0)] - else: - assert False, "no materialType found to match c[('u',0)].shape= %s " % c[('u',0)].shape - self.conservativeHeadRichardsMualemVanGenuchten_sd_het(self.sdInfo[(0,0)][0], - self.sdInfo[(0,0)][1], - materialTypes, - self.rho, - self.beta, - self.gravity, - self.vgm_alpha_types, - self.vgm_n_types, - self.thetaR_types, - self.thetaSR_types, - self.Ksw_types, - c[('u',0)], - c[('m',0)], - c[('dm',0,0)], - c[('f',0)], - c[('df',0,0)], - c[('a',0,0)], - c[('da',0,0,0)], - vol_frac) - # print "Picard---------------------------------------------------------------" - # c[('df',0,0)][:] = 0.0 - # c[('da',0,0,0)][:] = 0.0 -# self.conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2(materialTypes, -# self.rho, -# self.beta, -# self.gravity, -# self.vgm_alpha_types, -# self.vgm_n_types, -# self.thetaR_types, -# self.thetaSR_types, -# self.Ksw_types, -# c[('u',0)], -# c[('m',0)], -# c[('dm',0,0)], -# c[('f',0)], -# c[('df',0,0)], -# c[('a',0,0)], -# c[('da',0,0,0)]) - #mwf debug - if (np.isnan(c[('da',0,0,0)]).any() or - np.isnan(c[('a',0,0)]).any() or - np.isnan(c[('df',0,0)]).any() or - np.isnan(c[('f',0)]).any() or - np.isnan(c[('u',0)]).any() or - np.isnan(c[('m',0)]).any() or - np.isnan(c[('dm',0,0)]).any()): - import pdb - pdb.set_trace() - - def postStep(self, t, firstStep=False): - # #anb_seepage_flux_n[:]= self.anb_seepage_flux - with open('seepage_stab_0', "a") as f: - # f.write("\n Time"+ ",\t" +"Seepage\n") - f.write(repr(t)+ ",\t")# +repr(np.sum(self.LevelModel.anb_seepage_flux_n))) - -class LevelModel(proteus.Transport.OneLevelTransport): - nCalls=0 - def __init__(self, - uDict, - phiDict, - testSpaceDict, - matType, - dofBoundaryConditionsDict, - dofBoundaryConditionsSetterDict, - coefficients, - elementQuadrature, - elementBoundaryQuadrature, - fluxBoundaryConditionsDict=None, - advectiveFluxBoundaryConditionsSetterDict=None, - diffusiveFluxBoundaryConditionsSetterDictDict=None, - stressTraceBoundaryConditionsSetterDict=None, - stabilization=None, - shockCapturing=None, - conservativeFluxDict=None, - numericalFluxType=None, - TimeIntegrationClass=None, - massLumping=False, - reactionLumping=False, - options=None, - name='defaultName', - reuse_trial_and_test_quadrature=True, - sd = True, - movingDomain=False, - bdyNullSpace=False): - self.bdyNullSpace=bdyNullSpace - # - #set the objects describing the method and boundary conditions - # - self.movingDomain=movingDomain - self.tLast_mesh=None - # - self.name=name - self.sd=sd - self.Hess=False - self.lowmem=True - self.timeTerm=True#allow turning off the time derivative - #self.lowmem=False - self.testIsTrial=True - self.phiTrialIsTrial=True - self.u = uDict - self.ua = {}#analytical solutions - self.phi = phiDict - self.dphi={} - self.matType = matType - #mwf try to reuse test and trial information across components if spaces are the same - self.reuse_test_trial_quadrature = reuse_trial_and_test_quadrature#True#False - if self.reuse_test_trial_quadrature: - for ci in range(1,coefficients.nc): - assert self.u[ci].femSpace.__class__.__name__ == self.u[0].femSpace.__class__.__name__, "to reuse_test_trial_quad all femSpaces must be the same!" - self.u_dof_old = None - ## Simplicial Mesh - self.mesh = self.u[0].femSpace.mesh #assume the same mesh for all components for now - self.testSpace = testSpaceDict - self.dirichletConditions = dofBoundaryConditionsDict - self.dirichletNodeSetList=None #explicit Dirichlet conditions for now, no Dirichlet BC constraints - self.coefficients = coefficients - self.coefficients.initializeMesh(self.mesh) - self.nc = self.coefficients.nc - self.stabilization = stabilization - self.shockCapturing = shockCapturing - self.conservativeFlux = conservativeFluxDict #no velocity post-processing for now - self.fluxBoundaryConditions=fluxBoundaryConditionsDict - self.advectiveFluxBoundaryConditionsSetterDict=advectiveFluxBoundaryConditionsSetterDict - self.diffusiveFluxBoundaryConditionsSetterDictDict = diffusiveFluxBoundaryConditionsSetterDictDict - #determine whether the stabilization term is nonlinear - self.stabilizationIsNonlinear = False - #cek come back - if self.stabilization != None: - for ci in range(self.nc): - if ci in coefficients.mass: - for flag in list(coefficients.mass[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.advection: - for flag in list(coefficients.advection[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.diffusion: - for diffusionDict in list(coefficients.diffusion[ci].values()): - for flag in list(diffusionDict.values()): - if flag != 'constant': - self.stabilizationIsNonlinear=True - if ci in coefficients.potential: - for flag in list(coefficients.potential[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.reaction: - for flag in list(coefficients.reaction[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.hamiltonian: - for flag in list(coefficients.hamiltonian[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - #determine if we need element boundary storage - self.elementBoundaryIntegrals = {} - for ci in range(self.nc): - self.elementBoundaryIntegrals[ci] = ((self.conservativeFlux != None) or - (numericalFluxType != None) or - (self.fluxBoundaryConditions[ci] == 'outFlow') or - (self.fluxBoundaryConditions[ci] == 'mixedFlow') or - (self.fluxBoundaryConditions[ci] == 'setFlow')) - # - #calculate some dimensions - # - self.nSpace_global = self.u[0].femSpace.nSpace_global #assume same space dim for all variables - self.nDOF_trial_element = [u_j.femSpace.max_nDOF_element for u_j in list(self.u.values())] - self.nDOF_phi_trial_element = [phi_k.femSpace.max_nDOF_element for phi_k in list(self.phi.values())] - self.n_phi_ip_element = [phi_k.femSpace.referenceFiniteElement.interpolationConditions.nQuadraturePoints for phi_k in list(self.phi.values())] - self.nDOF_test_element = [femSpace.max_nDOF_element for femSpace in list(self.testSpace.values())] - self.nFreeDOF_global = [dc.nFreeDOF_global for dc in list(self.dirichletConditions.values())] - self.nVDOF_element = sum(self.nDOF_trial_element) - self.nFreeVDOF_global = sum(self.nFreeDOF_global) - # - NonlinearEquation.__init__(self,self.nFreeVDOF_global) - # - #build the quadrature point dictionaries from the input (this - #is just for convenience so that the input doesn't have to be - #complete) - # - elementQuadratureDict={} - elemQuadIsDict = isinstance(elementQuadrature,dict) - if elemQuadIsDict: #set terms manually - for I in self.coefficients.elementIntegralKeys: - if I in elementQuadrature: - elementQuadratureDict[I] = elementQuadrature[I] - - else: - elementQuadratureDict[I] = elementQuadrature['default'] - else: - for I in self.coefficients.elementIntegralKeys: - elementQuadratureDict[I] = elementQuadrature - if self.stabilization != None: - for I in self.coefficients.elementIntegralKeys: - if elemQuadIsDict: - if I in elementQuadrature: - elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature[I] - else: - elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature['default'] - else: - elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature - if self.shockCapturing != None: - for ci in self.shockCapturing.components: - if elemQuadIsDict: - if ('numDiff',ci,ci) in elementQuadrature: - elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature[('numDiff',ci,ci)] - #print("Hi, Arnob1") - #print(anb_seepage_flux) - else: - elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature['default'] - #print("Hi, Arnob2") - #print(anb_seepage_flux) - else: - elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature - print("Hi, Arnob3") - #print(anb_seepage_flux) - if massLumping: - for ci in list(self.coefficients.mass.keys()): - elementQuadratureDict[('m',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - print("Hi, Arnob4") - #print(anb_seepage_flux) - for I in self.coefficients.elementIntegralKeys: - elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - print("Hi, Arnob5") - #print(anb_seepage_flux) - if reactionLumping: - for ci in list(self.coefficients.mass.keys()): - elementQuadratureDict[('r',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - print("Hi, Arnob6") - #print(anb_seepage_flux) - for I in self.coefficients.elementIntegralKeys: - elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - print("Hi, Arnob7") - #print(anb_seepage_flux) - elementBoundaryQuadratureDict={} - if isinstance(elementBoundaryQuadrature,dict): #set terms manually - for I in self.coefficients.elementBoundaryIntegralKeys: - if I in elementBoundaryQuadrature: - elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature[I] - print("Hi, Arnob8") - #print(anb_seepage_flux) - else: - elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature['default'] - #print("Hi, Arnob9") - #print(anb_seepage_flux) - else: - for I in self.coefficients.elementBoundaryIntegralKeys: - elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature - print("Hi, Arnob10") - #print(anb_seepage_flux) - # - # find the union of all element quadrature points and - # build a quadrature rule for each integral that has a - # weight at each point in the union - #mwf include tag telling me which indices are which quadrature rule? - (self.elementQuadraturePoints,self.elementQuadratureWeights, - self.elementQuadratureRuleIndeces) = Quadrature.buildUnion(elementQuadratureDict) - self.nQuadraturePoints_element = self.elementQuadraturePoints.shape[0] - self.nQuadraturePoints_global = self.nQuadraturePoints_element*self.mesh.nElements_global - # - #Repeat the same thing for the element boundary quadrature - # - (self.elementBoundaryQuadraturePoints, - self.elementBoundaryQuadratureWeights, - self.elementBoundaryQuadratureRuleIndeces) = Quadrature.buildUnion(elementBoundaryQuadratureDict) - self.nElementBoundaryQuadraturePoints_elementBoundary = self.elementBoundaryQuadraturePoints.shape[0] - self.nElementBoundaryQuadraturePoints_global = (self.mesh.nElements_global* - self.mesh.nElementBoundaries_element* - self.nElementBoundaryQuadraturePoints_elementBoundary) -# if isinstance(self.u[0].femSpace,C0_AffineLinearOnSimplexWithNodalBasis): -# print self.nQuadraturePoints_element -# if self.nSpace_global == 3: -# assert(self.nQuadraturePoints_element == 5) -# elif self.nSpace_global == 2: -# assert(self.nQuadraturePoints_element == 6) -# elif self.nSpace_global == 1: -# assert(self.nQuadraturePoints_element == 3) -# -# print self.nElementBoundaryQuadraturePoints_elementBoundary -# if self.nSpace_global == 3: -# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) -# elif self.nSpace_global == 2: -# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) -# elif self.nSpace_global == 1: -# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 1) - - # - #storage dictionaries - self.scalars_element = set() - # - #simplified allocations for test==trial and also check if space is mixed or not - # - self.q={} - self.ebq={} - self.ebq_global={} - self.ebqe={} - self.phi_ip={} - self.edge_based_cfl = np.zeros(self.u[0].dof.shape)+100 - #mesh - #self.q['x'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,3),'d') - self.q[('dV_u', 0)] = (old_div(1.0, self.mesh.nElements_global)) * np.ones((self.mesh.nElements_global, self.nQuadraturePoints_element), 'd') - self.ebqe['x'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,3),'d') - self.q[('u',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') - self.q[('grad(u)',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') - self.q['velocity'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') - self.q[('m',0)] = self.q[('u',0)].copy() - self.q[('mt',0)] = self.q[('u',0)].copy() - self.q[('m_last',0)] = self.q[('u',0)].copy() - self.q[('m_tmp',0)] = self.q[('u',0)].copy() - self.q[('cfl',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') - self.q[('numDiff',0,0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') - self.ebqe[('u',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.ebqe[('grad(u)',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') - self.ebqe['velocity'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') - self.ebqe[('advectiveFlux_bc_flag',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'i') - self.ebqe[('advectiveFlux_bc',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.ebqe[('advectiveFlux',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.ebqe[('penalty')] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.points_elementBoundaryQuadrature= set() - self.scalars_elementBoundaryQuadrature= set([('u',ci) for ci in range(self.nc)]) - self.vectors_elementBoundaryQuadrature= set() - self.tensors_elementBoundaryQuadrature= set() - self.inflowBoundaryBC = {} - self.inflowBoundaryBC_values = {} - self.inflowFlux = {} - for cj in range(self.nc): - self.inflowBoundaryBC[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,),'i') - self.inflowBoundaryBC_values[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nDOF_trial_element[cj]),'d') - self.inflowFlux[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.internalNodes = set(range(self.mesh.nNodes_global)) - #identify the internal nodes this is ought to be in mesh - ##\todo move this to mesh - for ebNE in range(self.mesh.nExteriorElementBoundaries_global): - ebN = self.mesh.exteriorElementBoundariesArray[ebNE] - eN_global = self.mesh.elementBoundaryElementsArray[ebN,0] - ebN_element = self.mesh.elementBoundaryLocalElementBoundariesArray[ebN,0] - for i in range(self.mesh.nNodes_element): - if i != ebN_element: - I = self.mesh.elementNodesArray[eN_global,i] - self.internalNodes -= set([I]) - self.nNodes_internal = len(self.internalNodes) - self.internalNodesArray=np.zeros((self.nNodes_internal,),'i') - for nI,n in enumerate(self.internalNodes): - self.internalNodesArray[nI]=n - # - del self.internalNodes - self.internalNodes = None - logEvent("Updating local to global mappings",2) - self.updateLocal2Global() - logEvent("Building time integration object",2) - logEvent(memory("inflowBC, internalNodes,updateLocal2Global","OneLevelTransport"),level=4) - #mwf for interpolating subgrid error for gradients etc - if self.stabilization and self.stabilization.usesGradientStabilization: - self.timeIntegration = TimeIntegrationClass(self,integrateInterpolationPoints=True) - else: - self.timeIntegration = TimeIntegrationClass(self) - - if options != None: - self.timeIntegration.setFromOptions(options) - logEvent(memory("TimeIntegration","OneLevelTransport"),level=4) - logEvent("Calculating numerical quadrature formulas",2) - self.calculateQuadrature() - #lay out components/equations contiguously for now - self.offset = [0] - for ci in range(1,self.nc): - self.offset += [self.offset[ci-1]+self.nFreeDOF_global[ci-1]] - self.stride = [1 for ci in range(self.nc)] - #use contiguous layout of components for parallel, requires weak DBC's - # mql. Some ASSERTS to restrict the combination of the methods - if self.coefficients.STABILIZATION_TYPE > 0: - pass - #assert self.timeIntegration.isSSP == True, "If STABILIZATION_TYPE>0, use RKEV timeIntegration within VOF model" - #cond = 'levelNonlinearSolver' in dir(options) and (options.levelNonlinearSolver == - # ExplicitLumpedMassMatrixForRichards or options.levelNonlinearSolver == ExplicitConsistentMassMatrixForRichards) - #assert cond, "If STABILIZATION_TYPE>0, use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards or ExplicitConsistentMassMatrixForRichards" - try: - if 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards: - assert self.coefficients.LUMPED_MASS_MATRIX, "If levelNonlinearSolver=ExplicitLumpedMassMatrix, use LUMPED_MASS_MATRIX=True" - except: - pass - if self.coefficients.LUMPED_MASS_MATRIX == True: - cond = self.coefficients.STABILIZATION_TYPE == 2 - assert cond, "Use lumped mass matrix just with: STABILIZATION_TYPE=2 (smoothness based stab.)" - cond = 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards - assert cond, "Use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards when the mass matrix is lumped" - if self.coefficients.FCT == True: - cond = self.coefficients.STABILIZATION_TYPE > 0, "Use FCT just with STABILIZATION_TYPE>0; i.e., edge based stabilization" - # END OF ASSERTS - - # cek adding empty data member for low order numerical viscosity structures here for now - self.ML = None # lumped mass matrix - self.MC_global = None # consistent mass matrix - self.cterm_global = None - self.cterm_transpose_global = None - # dL_global and dC_global are not the full matrices but just the CSR arrays containing the non zero entries - self.residualComputed=False #TMP - self.dLow= None - self.fluxMatrix = None - self.uDotLow = None - self.uLow = None - self.dt_times_dC_minus_dL = None - self.min_s_bc = None - self.max_s_bc = None - # Aux quantity at DOFs to be filled by optimized code (MQL) - self.quantDOFs = np.zeros(self.u[0].dof.shape, 'd') - self.sLow = np.zeros(self.u[0].dof.shape, 'd') - self.sHigh = np.zeros(self.u[0].dof.shape, 'd') - self.sn = np.zeros(self.u[0].dof.shape, 'd') - self.anb_seepage_flux_n = np.zeros(self.u[0].dof.shape, 'd') - comm = Comm.get() - self.comm=comm - if comm.size() > 1: - assert numericalFluxType != None and numericalFluxType.useWeakDirichletConditions,"You must use a numerical flux to apply weak boundary conditions for parallel runs" - self.offset = [0] - for ci in range(1,self.nc): - self.offset += [ci] - self.stride = [self.nc for ci in range(self.nc)] - # - logEvent(memory("stride+offset","OneLevelTransport"),level=4) - - - if numericalFluxType != None: - if options is None or options.periodicDirichletConditions is None: - self.numericalFlux = numericalFluxType(self, - dofBoundaryConditionsSetterDict, - advectiveFluxBoundaryConditionsSetterDict, - diffusiveFluxBoundaryConditionsSetterDictDict) - else: - self.numericalFlux = numericalFluxType(self, - dofBoundaryConditionsSetterDict, - advectiveFluxBoundaryConditionsSetterDict, - diffusiveFluxBoundaryConditionsSetterDictDict, - options.periodicDirichletConditions) - else: - self.numericalFlux = None - #set penalty terms - #cek todo move into numerical flux initialization - if 'penalty' in self.ebq_global: - for ebN in range(self.mesh.nElementBoundaries_global): - for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): - self.ebq_global['penalty'][ebN,k] = old_div(self.numericalFlux.penalty_constant,(self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power)) - #penalty term - #cek move to Numerical flux initialization - if 'penalty' in self.ebqe: - for ebNE in range(self.mesh.nExteriorElementBoundaries_global): - ebN = self.mesh.exteriorElementBoundariesArray[ebNE] - for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): - self.ebqe['penalty'][ebNE,k] = old_div(self.numericalFlux.penalty_constant,self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power) - logEvent(memory("numericalFlux","OneLevelTransport"),level=4) - self.elementEffectiveDiametersArray = self.mesh.elementInnerDiametersArray - #use post processing tools to get conservative fluxes, None by default - from proteus import PostProcessingTools - self.velocityPostProcessor = PostProcessingTools.VelocityPostProcessingChooser(self) - logEvent(memory("velocity postprocessor","OneLevelTransport"),level=4) - #helper for writing out data storage - from proteus import Archiver - self.elementQuadratureDictionaryWriter = Archiver.XdmfWriter() - self.elementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() - self.exteriorElementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() - #TODO get rid of this - for ci,fbcObject in list(self.fluxBoundaryConditionsObjectsDict.items()): - self.ebqe[('advectiveFlux_bc_flag',ci)] = np.zeros(self.ebqe[('advectiveFlux_bc',ci)].shape,'i') - for t,g in list(fbcObject.advectiveFluxBoundaryConditionsDict.items()): - if ci in self.coefficients.advection: - self.ebqe[('advectiveFlux_bc',ci)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) - self.ebqe[('advectiveFlux_bc_flag',ci)][t[0],t[1]] = 1 - - if hasattr(self.numericalFlux,'setDirichletValues'): - self.numericalFlux.setDirichletValues(self.ebqe) - if not hasattr(self.numericalFlux,'isDOFBoundary'): - self.numericalFlux.isDOFBoundary = {0:np.zeros(self.ebqe[('u',0)].shape,'i')} - if not hasattr(self.numericalFlux,'ebqe'): - self.numericalFlux.ebqe = {('u',0):np.zeros(self.ebqe[('u',0)].shape,'d')} - #TODO how to handle redistancing calls for calculateCoefficients,calculateElementResidual etc - self.globalResidualDummy = None - compKernelFlag=0 - self.delta_x_ij=None - self.richards = cRichards_base(self.nSpace_global, - self.nQuadraturePoints_element, - self.u[0].femSpace.elementMaps.localFunctionSpace.dim, - self.u[0].femSpace.referenceFiniteElement.localFunctionSpace.dim, - self.testSpace[0].referenceFiniteElement.localFunctionSpace.dim, - self.nElementBoundaryQuadraturePoints_elementBoundary, - compKernelFlag) - if self.movingDomain: - self.MOVING_DOMAIN=1.0 - else: - self.MOVING_DOMAIN=0.0 - #cek hack - self.movingDomain=False - self.MOVING_DOMAIN=0.0 - if self.mesh.nodeVelocityArray is None: - self.mesh.nodeVelocityArray = np.zeros(self.mesh.nodeArray.shape,'d') - self.forceStrongConditions=True - self.dirichletConditionsForceDOF = {} - if self.forceStrongConditions: - for cj in range(self.nc): - self.dirichletConditionsForceDOF[cj] = DOFBoundaryConditions(self.u[cj].femSpace,dofBoundaryConditionsSetterDict[cj],weakDirichletConditions=False) - def FCTStep(self): - import pdb - rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() - limited_solution = np.zeros((len(rowptr) - 1),'d') - #self.u_free_dof_stage_0_l = np.zeros((len(rowptr) - 1),'d') - #self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage], # soln - #fromFreeToGlobal=0 - #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - # self.offset[0], - # self.stride[0], - # self.dirichletConditions[0].global2freeGlobal_global_dofs, - # self.dirichletConditions[0].global2freeGlobal_free_dofs, - # self.u_free_dof_stage_0_l, - # self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage]) - argsDict = cArgumentsDict.ArgumentsDict() - argsDict["bc_mask"] = self.bc_mask - argsDict["NNZ"] = self.nnz - argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs - argsDict["dt"] = self.timeIntegration.dt - argsDict["lumped_mass_matrix"] = self.ML - argsDict["soln"] = self.sn - argsDict["pn"] = self.u[0].dof - argsDict["solH"] = self.sHigh - argsDict["uLow"] = self.sLow - argsDict["uDotLow"] = self.uDotLow - argsDict["limited_solution"] = limited_solution - argsDict["csrRowIndeces_DofLoops"] = rowptr - argsDict["csrColumnOffsets_DofLoops"] = colind - argsDict["MassMatrix"] = MassMatrix - argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL - argsDict["min_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0]) #cek hack just set from physical bounds - argsDict["max_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0] + self.coefficients.thetaSR_types[0]) #cek hack - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - argsDict["MONOLITHIC"] =0#cek hack self.coefficients.MONOLITHIC - argsDict["anb_seepage_flux_n"]= self.anb_seepage_flux_n - #pdb.set_trace() - self.richards.FCTStep(argsDict) - - # self.nnz, # number of non zero entries - # len(rowptr) - 1, # number of DOFs - # self.timeIntegration.dt, - # self.ML, # Lumped mass matrix - # self.sn, - # self.u_dof_old, - # self.sHigh, # high order solution - # self.sLow, - # limited_solution, - # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) - # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) - # MassMatrix, - # self.dt_times_dC_minus_dL, - # self.min_s_bc, - # self.max_s_bc, - # self.coefficients.LUMPED_MASS_MATRIX, - # self.coefficients.MONOLITHIC) - old_dof = self.u[0].dof.copy() - self.invert(limited_solution, self.u[0].dof) - self.timeIntegration.u[:] = self.u[0].dof - #fromFreeToGlobal=1 #direction copying - #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - # self.offset[0], - # self.stride[0], - # self.dirichletConditions[0].global2freeGlobal_global_dofs, - # self.dirichletConditions[0].global2freeGlobal_free_dofs, - # self.u[0].dof, - # limited_solution) - def kth_FCT_step(self): - #import pdb - #pdb.set_trace() - rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() - limitedFlux = np.zeros(self.nnz) - limited_solution = np.zeros((len(rowptr) - 1),'d') - #limited_solution[:] = self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage] - fromFreeToGlobal=0 #direction copying - cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - self.offset[0], - self.stride[0], - self.dirichletConditions[0].global2freeGlobal_global_dofs, - self.dirichletConditions[0].global2freeGlobal_free_dofs, - limited_solution, - self.timeintegration.u_dof_stage[0][self.timeIntegration.lstage]) - - self.richards.kth_FCT_step( - self.timeIntegration.dt, - self.coefficients.num_fct_iter, - self.nnz, # number of non zero entries - len(rowptr) - 1, # number of DOFs - MassMatrix, - self.ML, # Lumped mass matrix - self.u_dof_old, - limited_solution, - self.uDotLow, - self.uLow, - self.dLow, - self.fluxMatrix, - limitedFlux, - rowptr, - colind) - - self.timeIntegration.u[:] = limited_solution - #self.u[0].dof[:] = limited_solution - fromFreeToGlobal=1 #direction copying - cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - self.offset[0], - self.stride[0], - self.dirichletConditions[0].global2freeGlobal_global_dofs, - self.dirichletConditions[0].global2freeGlobal_free_dofs, - self.u[0].dof, - limited_solution) - def calculateCoefficients(self): - pass - def calculateElementResidual(self): - if self.globalResidualDummy != None: - self.getResidual(self.u[0].dof,self.globalResidualDummy) - def getResidual(self,u,r): - import pdb - import copy - """ - Calculate the element residuals and add in to the global residual - """ - cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, - self.jacobian) - if self.u_dof_old is None: - # Pass initial condition to u_dof_old - self.u_dof_old = np.copy(self.u[0].dof) - rowptr, colind, nzval = self.jacobian.getCSRrepresentation() - nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix - r.fill(0.0) - ######################## - ### COMPUTE C MATRIX ### - ######################## - if self.cterm_global is None: - # since we only need cterm_global to persist, we can drop the other self.'s - self.cterm = {} - self.cterm_a = {} - self.cterm_global = {} - self.cterm_transpose = {} - self.cterm_a_transpose = {} - self.cterm_global_transpose = {} - rowptr, colind, nzval = self.jacobian.getCSRrepresentation() - nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix - di = self.q[('grad(u)', 0)].copy() # direction of derivative - # JACOBIANS (FOR ELEMENT TRANSFORMATION) - self.q[('J')] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nSpace_global, - self.nSpace_global), - 'd') - self.q[('inverse(J)')] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nSpace_global, - self.nSpace_global), - 'd') - self.q[('det(J)')] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element), - 'd') - self.u[0].femSpace.elementMaps.getJacobianValues(self.elementQuadraturePoints, - self.q['J'], - self.q['inverse(J)'], - self.q['det(J)']) - self.q['abs(det(J))'] = np.abs(self.q['det(J)']) - # SHAPE FUNCTIONS - self.q[('w', 0)] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nDOF_test_element[0]), - 'd') - self.q[('w*dV_m', 0)] = self.q[('w', 0)].copy() - self.u[0].femSpace.getBasisValues(self.elementQuadraturePoints, self.q[('w', 0)]) - cfemIntegrals.calculateWeightedShape(self.elementQuadratureWeights[('u', 0)], - self.q['abs(det(J))'], - self.q[('w', 0)], - self.q[('w*dV_m', 0)]) - # GRADIENT OF TEST FUNCTIONS - self.q[('grad(w)', 0)] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nDOF_test_element[0], - self.nSpace_global), - 'd') - self.u[0].femSpace.getBasisGradientValues(self.elementQuadraturePoints, - self.q['inverse(J)'], - self.q[('grad(w)', 0)]) - self.q[('grad(w)*dV_f', 0)] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nDOF_test_element[0], - self.nSpace_global), - 'd') - cfemIntegrals.calculateWeightedShapeGradients(self.elementQuadratureWeights[('u', 0)], - self.q['abs(det(J))'], - self.q[('grad(w)', 0)], - self.q[('grad(w)*dV_f', 0)]) - ########################## - ### LUMPED MASS MATRIX ### - ########################## - # assume a linear mass term - dm = np.ones(self.q[('u', 0)].shape, 'd') - elementMassMatrix = np.zeros((self.mesh.nElements_global, - self.nDOF_test_element[0], - self.nDOF_trial_element[0]), 'd') - cfemIntegrals.updateMassJacobian_weak_lowmem(dm, - self.q[('w', 0)], - self.q[('w*dV_m', 0)], - elementMassMatrix) - self.MC_a = nzval.copy() - self.MC_global = SparseMat(self.nFreeDOF_global[0], - self.nFreeDOF_global[0], - nnz, - self.MC_a, - colind, - rowptr) - cfemIntegrals.zeroJacobian_CSR(self.nnz, self.MC_global) - cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.csrRowIndeces[(0, 0)], - self.csrColumnOffsets[(0, 0)], - elementMassMatrix, - self.MC_global) - self.ML = np.zeros((self.nFreeDOF_global[0],), 'd') - for i in range(self.nFreeDOF_global[0]): - self.ML[i] = self.MC_a[rowptr[i]:rowptr[i + 1]].sum() - np.testing.assert_almost_equal(self.ML.sum(), - self.mesh.volume, - err_msg="Trace of lumped mass matrix should be the domain volume", verbose=True) - for d in range(self.nSpace_global): # spatial dimensions - # C matrices - self.cterm[d] = np.zeros((self.mesh.nElements_global, - self.nDOF_test_element[0], - self.nDOF_trial_element[0]), 'd') - self.cterm_a[d] = nzval.copy() - #self.cterm_a[d] = np.zeros(nzval.size) - self.cterm_global[d] = SparseMat(self.nFreeDOF_global[0], - self.nFreeDOF_global[0], - nnz, - self.cterm_a[d], - colind, - rowptr) - cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global[d]) - di[:] = 0.0 - di[..., d] = 1.0 - cfemIntegrals.updateHamiltonianJacobian_weak_lowmem(di, - self.q[('grad(w)*dV_f', 0)], - self.q[('w', 0)], - self.cterm[d]) # int[(di*grad(wj))*wi*dV] - cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.csrRowIndeces[(0, 0)], - self.csrColumnOffsets[(0, 0)], - self.cterm[d], - self.cterm_global[d]) - # C Transpose matrices - self.cterm_transpose[d] = np.zeros((self.mesh.nElements_global, - self.nDOF_test_element[0], - self.nDOF_trial_element[0]), 'd') - self.cterm_a_transpose[d] = nzval.copy() - self.cterm_global_transpose[d] = SparseMat(self.nFreeDOF_global[0], - self.nFreeDOF_global[0], - nnz, - self.cterm_a_transpose[d], - colind, - rowptr) - cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global_transpose[d]) - di[:] = 0.0 - di[..., d] = -1.0 - cfemIntegrals.updateAdvectionJacobian_weak_lowmem(di, - self.q[('w', 0)], - self.q[('grad(w)*dV_f', 0)], - self.cterm_transpose[d]) # -int[(-di*grad(wi))*wj*dV] - cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.csrRowIndeces[(0, 0)], - self.csrColumnOffsets[(0, 0)], - self.cterm_transpose[d], - self.cterm_global_transpose[d]) - - rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() - else: - Cy = np.zeros(Cx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() - else: - Cz = np.zeros(Cx.shape, 'd') - rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() - else: - CTy = np.zeros(CTx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() - else: - CTz = np.zeros(CTx.shape, 'd') - - # This is dummy. I just care about the csr structure of the sparse matrix - self.dLow = np.zeros(Cx.shape, 'd') - self.fluxMatrix = np.zeros(Cx.shape, 'd') - self.dt_times_dC_minus_dL = np.zeros(Cx.shape, 'd') - nFree = len(rowptr)-1 - self.min_s_bc = np.zeros(nFree, 'd') + 1E10 - self.max_s_bc = np.zeros(nFree, 'd') - 1E10 - self.uDotLow = np.zeros(nFree, 'd') - self.uLow = np.zeros(nFree, 'd') - # - # cek end computationa of cterm_global - # - # cek showing mquezada an example of using cterm_global sparse matrix - # calculation y = c*x where x==1 - # direction=0 - #rowptr, colind, c = self.cterm_global[direction].getCSRrepresentation() - #y = np.zeros((self.nFreeDOF_global[0],),'d') - #x = np.ones((self.nFreeDOF_global[0],),'d') - # ij=0 - # for i in range(self.nFreeDOF_global[0]): - # for offset in range(rowptr[i],rowptr[i+1]): - # j = colind[offset] - # y[i] += c[ij]*x[j] - # ij+=1 - #Load the unknowns into the finite element dof - self.timeIntegration.calculateCoefs() - self.timeIntegration.calculateU(u) - self.setUnknowns(self.timeIntegration.u) - #cek can put in logic to skip of BC's don't depend on t or u - #Dirichlet boundary conditions - self.numericalFlux.setDirichletValues(self.ebqe) - #flux boundary conditions - #cek hack, just using advective flux for flux BC for now - for t,g in list(self.fluxBoundaryConditionsObjectsDict[0].advectiveFluxBoundaryConditionsDict.items()): - self.ebqe[('advectiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) - self.ebqe[('advectiveFlux_bc_flag',0)][t[0],t[1]] = 1 - # for t,g in self.fluxBoundaryConditionsObjectsDict[0].diffusiveFluxBoundaryConditionsDict.iteritems(): - # self.ebqe[('diffusiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) - # self.ebqe[('diffusiveFlux_bc_flag',0)][t[0],t[1]] = 1 - #self.shockCapturing.lag=True - if self.forceStrongConditions: - self.bc_mask = np.ones_like(self.u[0].dof) - for cj in range(len(self.dirichletConditionsForceDOF)): - for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): - self.u[cj].dof[dofN] = g(self.dirichletConditionsForceDOF[cj].DOFBoundaryPointDict[dofN],self.timeIntegration.t) - self.u_dof_old[dofN] = self.u[cj].dof[dofN] - self.bc_mask[dofN] = 0.0 - degree_polynomial = 1 - try: - degree_polynomial = self.u[0].femSpace.order - except: - pass - - argsDict = cArgumentsDict.ArgumentsDict() - argsDict["bc_mask"] = self.bc_mask - argsDict["dt"] = self.timeIntegration.dt - argsDict["Theta"] = 1.0 - argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi - argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi - argsDict["mesh_dof"] = self.mesh.nodeArray - argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray - argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN - argsDict["mesh_l2g"] = self.mesh.elementNodesArray - argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] - argsDict["u_trial_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi - argsDict["u_test_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi - argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace - argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace - argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] - argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals - argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians - argsDict["nElements_global"] = self.mesh.nElements_global - argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] - argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, - argsDict["isSeepageFace"] = self.coefficients.isSeepageFace - argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] - argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] - argsDict["rho"] = self.coefficients.rho - argsDict["beta"] = self.coefficients.beta - argsDict["gravity"] = self.coefficients.gravity - argsDict["alpha"] = self.coefficients.vgm_alpha_types - argsDict["n"] = self.coefficients.vgm_n_types - argsDict["thetaR"] = self.coefficients.thetaR_types - argsDict["thetaSR"] = self.coefficients.thetaSR_types - argsDict["KWs"] = self.coefficients.Ksw_types - argsDict["useMetrics"] = 0.0 - argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf - argsDict["lag_shockCapturing"] = 0 - argsDict["shockCapturingDiffusion"] = 0.0 - argsDict["sc_uref"] = 0.0 - argsDict["sc_alpha"] = 0.0 - argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g - argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] - argsDict["elementDiameter"] = self.mesh.elementDiametersArray - argsDict["degree_polynomial"] = degree_polynomial - argsDict["u_dof"] = self.u[0].dof - argsDict["u_dof_old"] = self.u_dof_old - argsDict["velocity"] = self.q['velocity'] - argsDict["q_m"] = self.timeIntegration.m_tmp[0] - argsDict["q_u"] = self.q[('u',0)] - argsDict["q_dV"] = self.q[('dV_u',0)] - argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] - argsDict["cfl"] = self.q[('cfl',0)] - argsDict["q_numDiff_u"] = self.q[('cfl',0)] - argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] - argsDict["offset_u"] = self.offset[0] - argsDict["stride_u"] = self.stride[0] - argsDict["globalResidual"] = r - argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global - argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray - argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray - argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray - argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] - argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] - argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] - argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] - argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] - argsDict["ebqe_phi"] = self.ebqe[('u',0)] - argsDict["epsFact"] = 0.0 - argsDict["ebqe_u"] = self.ebqe[('u',0)] - argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] - argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE - # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION - argsDict["cE"] = self.coefficients.cE - argsDict["cK"] = self.coefficients.cK - # PARAMETERS FOR LOG BASED ENTROPY FUNCTION - argsDict["uL"] = self.coefficients.uL - argsDict["uR"] = self.coefficients.uR - # PARAMETERS FOR EDGE VISCOSITY - argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs - argsDict["NNZ"] = self.nnz - argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern - argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) - argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) - argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms - argsDict["globalJacobian"] = self.jacobian.getCSRrepresentation()[2] - # C matrices - argsDict["Cx"] = Cx - argsDict["Cy"] = Cy - argsDict["Cz"] = Cz - argsDict["CTx"] = CTx - argsDict["CTy"] = CTy - argsDict["CTz"] = CTz - argsDict["ML"] = self.ML - argsDict["delta_x_ij"] = self.delta_x_ij - # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE - argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE - # FLUX CORRECTED TRANSPORT - argsDict["dLow"] = self.dLow - argsDict["fluxMatrix"] = self.fluxMatrix - argsDict["uDotLow"] = self.uDotLow - argsDict["uLow"] = self.uLow - argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL - argsDict["min_s_bc"] = self.min_s_bc - argsDict["max_s_bc"] = self.max_s_bc - argsDict["quantDOFs"] = self.quantDOFs - argsDict["sLow"] = self.sLow - argsDict["sn"] = self.sn - argsDict["anb_seepage_flux_n"]= self.anb_seepage_flux_n - - argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - #print(anb_seepage_flux) - #argsDict["anb_seepage_flux_n"] = self.coefficients.anb_seepage_flux_n - #if np.sum(anb_seepage_flux_n)>0: - - #logEvent("Hi, this is Arnob", self.anb_seepage_flux_n[0]) - print("Seepage Flux from Python file", np.sum(self.anb_seepage_flux_n)) - seepage_text_variable= np.sum(self.anb_seepage_flux_n) - - with open('seepage_stab_0',"a" ) as f: - #f.write("\n Time"+ ",\t" +"Seepage\n") - #f.write(repr(self.coefficients.t)+ ",\t" +repr(seepage_text_variable), "\n") - f.write(repr(seepage_text_variable)+ "\n") - if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG - self.calculateResidual = self.richards.calculateResidual - self.calculateJacobian = self.richards.calculateJacobian - else: - self.calculateResidual = self.richards.calculateResidual_entropy_viscosity - self.calculateJacobian = self.richards.calculateMassMatrix - if self.delta_x_ij is None: - self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') - self.calculateResidual(argsDict) - #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] - #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf - #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] - #self.timeIntegration.calculateElementCoefficients(self.q) - if self.forceStrongConditions:# - for cj in range(len(self.dirichletConditionsForceDOF)):# - for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): - r[self.offset[cj]+self.stride[cj]*dofN] = 0 - if self.stabilization: - self.stabilization.accumulateSubgridMassHistory(self.q) - logEvent("Global residual",level=9,data=r) - self.nonlinear_function_evaluations += 1 - if self.globalResidualDummy is None: - self.globalResidualDummy = np.zeros(r.shape,'d') - - #print("Hello from the python file", self.coefficients.anb_seepage_flux) - #logEvent("Hello from the python file", self.coefficients.anb_seepage_flux") - - - - - - def invert(self,u,r): - #u=s - #r=p - import pdb - import copy - """ - Calculate the element residuals and add in to the global residual - """ - self.sHigh[:] = u - rowptr, colind, nzval = self.jacobian.getCSRrepresentation() - nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix - r.fill(0.0) - rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() - else: - Cy = np.zeros(Cx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() - else: - Cz = np.zeros(Cx.shape, 'd') - rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() - else: - CTy = np.zeros(CTx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() - else: - CTz = np.zeros(CTx.shape, 'd') - - # This is dummy. I just care about the csr structure of the sparse matrix - nFree = len(rowptr)-1 - degree_polynomial = 1 - try: - degree_polynomial = self.u[0].femSpace.order - except: - pass - if self.delta_x_ij is None: - self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') - argsDict = cArgumentsDict.ArgumentsDict() - argsDict["dt"] = self.timeIntegration.dt - argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi - argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi - argsDict["mesh_dof"] = self.mesh.nodeArray - argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray - argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN - argsDict["mesh_l2g"] = self.mesh.elementNodesArray - argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] - argsDict["u_trial_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi - argsDict["u_test_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi - argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace - argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace - argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] - argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals - argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians - argsDict["nElements_global"] = self.mesh.nElements_global - argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] - argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, - argsDict["isSeepageFace"] = self.coefficients.isSeepageFace - argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] - argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] - argsDict["rho"] = self.coefficients.rho - argsDict["beta"] = self.coefficients.beta - argsDict["gravity"] = self.coefficients.gravity - argsDict["alpha"] = self.coefficients.vgm_alpha_types - argsDict["n"] = self.coefficients.vgm_n_types - argsDict["thetaR"] = self.coefficients.thetaR_types - argsDict["thetaSR"] = self.coefficients.thetaSR_types - argsDict["KWs"] = self.coefficients.Ksw_types - argsDict["useMetrics"] = 0.0 - argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf - argsDict["lag_shockCapturing"] = 0 - argsDict["shockCapturingDiffusion"] = 0.0 - argsDict["sc_uref"] = 0.0 - argsDict["sc_alpha"] = 0.0 - argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g - argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] - argsDict["elementDiameter"] = self.mesh.elementDiametersArray - argsDict["degree_polynomial"] = degree_polynomial - argsDict["u_dof"] = u#self.u[0].dof - argsDict["u_dof_old"] = self.u[0].dof - argsDict["velocity"] = self.q['velocity'] - argsDict["q_m"] = self.timeIntegration.m_tmp[0] - argsDict["q_u"] = self.q[('u',0)] - argsDict["q_dV"] = self.q[('dV_u',0)] - argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] - argsDict["cfl"] = self.q[('cfl',0)] - argsDict["q_numDiff_u"] = self.q[('cfl',0)] - argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] - argsDict["offset_u"] = self.offset[0] - argsDict["stride_u"] = self.stride[0] - argsDict["globalResidual"] = r - argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global - argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray - argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray - argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray - argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] - argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] - argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] - argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] - argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] - argsDict["ebqe_phi"] = self.ebqe[('u',0)] - argsDict["epsFact"] = 0.0 - argsDict["ebqe_u"] = self.ebqe[('u',0)] - argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] - argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE - # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION - argsDict["cE"] = self.coefficients.cE - argsDict["cK"] = self.coefficients.cK - # PARAMETERS FOR LOG BASED ENTROPY FUNCTION - argsDict["uL"] = self.coefficients.uL - argsDict["uR"] = self.coefficients.uR - # PARAMETERS FOR EDGE VISCOSITY - argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs - argsDict["NNZ"] = self.nnz - argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern - argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) - argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) - argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms - # C matrices - argsDict["Cx"] = Cx - argsDict["Cy"] = Cy - argsDict["Cz"] = Cz - argsDict["CTx"] = CTx - argsDict["CTy"] = CTy - argsDict["CTz"] = CTz - argsDict["ML"] = self.ML - argsDict["delta_x_ij"] = self.delta_x_ij - # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE - argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE - # FLUX CORRECTED TRANSPORT - argsDict["dLow"] = self.dLow - argsDict["fluxMatrix"] = self.fluxMatrix - argsDict["uDotLow"] = self.uDotLow - argsDict["uLow"] = self.uLow - argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL - argsDict["min_s_bc"] = self.min_s_bc - argsDict["max_s_bc"] = self.max_s_bc - argsDict["quantDOFs"] = self.quantDOFs - argsDict["sLow"] = self.sLow - argsDict["sn"] = self.sn - #Arnob trying to print flux - argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - #print("Hi",anb_seepage_flux) - #print("Hi Seepage Flux", self.coefficients.anb_seepage_flux) - - self.richards.invert(argsDict) - # self.timeIntegration.dt, - # self.u[0].femSpace.elementMaps.psi, - # self.u[0].femSpace.elementMaps.grad_psi, - # self.mesh.nodeArray, - # self.mesh.nodeVelocityArray, - # self.MOVING_DOMAIN, - # self.mesh.elementNodesArray, - # self.elementQuadratureWeights[('u',0)], - # self.u[0].femSpace.psi, - # self.u[0].femSpace.grad_psi, - # self.u[0].femSpace.psi, - # self.u[0].femSpace.grad_psi, - # #element boundary - # self.u[0].femSpace.elementMaps.psi_trace, - # self.u[0].femSpace.elementMaps.grad_psi_trace, - # self.elementBoundaryQuadratureWeights[('u',0)], - # self.u[0].femSpace.psi_trace, - # self.u[0].femSpace.grad_psi_trace, - # self.u[0].femSpace.psi_trace, - # self.u[0].femSpace.grad_psi_trace, - # self.u[0].femSpace.elementMaps.boundaryNormals, - # self.u[0].femSpace.elementMaps.boundaryJacobians, - # #physics - # self.mesh.nElements_global, - # self.ebqe['penalty'],#double* ebqe_penalty_ext, - # self.mesh.elementMaterialTypes,#int* elementMaterialTypes, - # self.coefficients.isSeepageFace, - # self.coefficients.sdInfo[(0,0)][0],#int* a_rowptr, - # self.coefficients.sdInfo[(0,0)][1],#int* a_colind, - # self.coefficients.rho,#double rho, - # self.coefficients.beta,#double beta, - # self.coefficients.gravity,#double* gravity, - # self.coefficients.vgm_alpha_types,#double* alpha, - # self.coefficients.vgm_n_types,#double* n, - # self.coefficients.thetaR_types,#double* thetaR, - # self.coefficients.thetaSR_types,#double* thetaSR, - # self.coefficients.Ksw_types,#double* KWs, - # False,#self.coefficients.useMetrics, - # self.timeIntegration.alpha_bdf, - # 0,#self.shockCapturing.lag, - # 0.0,#cek hack self.shockCapturing.shockCapturingFactor, - # 0.0,#self.coefficients.sc_uref, - # 0.0,#self.coefficients.sc_beta, - # self.u[0].femSpace.dofMap.l2g, - # self.l2g[0]['freeGlobal'], - # self.mesh.elementDiametersArray, - # degree_polynomial, - # self.sHigh, - # self.u_dof_old, - # self.q['velocity'],#self.coefficients.q_v, - # self.timeIntegration.m_tmp[0], - # self.q[('u',0)], - # self.timeIntegration.beta_bdf[0], - # self.q[('cfl',0)], - # self.edge_based_cfl, - # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff[0], - # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff_last[0], - # self.offset[0],self.stride[0], - # r, - # self.mesh.nExteriorElementBoundaries_global, - # self.mesh.exteriorElementBoundariesArray, - # self.mesh.elementBoundaryElementsArray, - # self.mesh.elementBoundaryLocalElementBoundariesArray, - # self.ebqe['velocity'],#self.coefficients.ebqe_v, - # self.numericalFlux.isDOFBoundary[0], - # self.numericalFlux.ebqe[('u',0)], - # self.ebqe[('advectiveFlux_bc_flag',0)], - # self.ebqe[('advectiveFlux_bc',0)], - # self.ebqe[('u',0)],#cek hack self.coefficients.ebqe_phi, - # 0.0,#cek hack self.coefficients.epsFact, - # self.ebqe[('u',0)], - # self.ebqe[('advectiveFlux',0)], - # # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION - # self.coefficients.cE, - # self.coefficients.cK, - # # PARAMETERS FOR LOG BASED ENTROPY FUNCTION - # self.coefficients.uL, - # self.coefficients.uR, - # # PARAMETERS FOR EDGE VISCOSITY - # len(rowptr) - 1, # num of DOFs - # len(Cx), # num of non-zero entries in the sparsity pattern - # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) - # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) - # self.csrRowIndeces[(0, 0)], # row indices (convenient for element loops) - # self.csrColumnOffsets[(0, 0)], # column indices (convenient for element loops) - # self.csrColumnOffsets_eb[(0, 0)], # indices for boundary terms - # # C matrices - # Cx, - # Cy, - # Cz, - # CTx, - # CTy, - # CTz, - # self.ML, - # self.delta_x_ij, - # # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - # self.coefficients.LUMPED_MASS_MATRIX, - # self.coefficients.STABILIZATION_TYPE, - # self.coefficients.ENTROPY_TYPE, - # # FLUX CORRECTED TRANSPORT - # self.dLow, - # self.fluxMatrix, - # self.uDotLow, - # self.uLow, - # self.dt_times_dC_minus_dL, - # self.min_s_bc, - # self.max_s_bc, - # self.quantDOFs) - #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] - #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf - #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] - #self.timeIntegration.calculateElementCoefficients(self.q) - #if self.forceStrongConditions:# - # for cj in range(len(self.dirichletConditionsForceDOF)):# - # for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): - # r[self.offset[cj]+self.stride[cj]*dofN] = 0 - #if self.stabilization: - # self.stabilization.accumulateSubgridMassHistory(self.q) - #logEvent("Global residual",level=9,data=r) - #self.nonlinear_function_evaluations += 1 - #if self.globalResidualDummy is None: - # self.globalResidualDummy = numpy.zeros(r.shape,'d') - def postStep(self, t, firstStep=False): - with open('seepage_flux_nnnn', "a") as f: - f.write("\n Time"+ ",\t" +"Seepage\n") - f.write(repr(t)+ ",\t" +repr(self.coefficients.anb_seepage_flux)) - def getJacobian(self,jacobian): - if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG - cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, - jacobian) - degree_polynomial = 1 - try: - degree_polynomial = self.u[0].femSpace.order - except: - pass - if self.delta_x_ij is None: - self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') - argsDict = cArgumentsDict.ArgumentsDict() - argsDict["dt"] = self.timeIntegration.dt - argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi - argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi - argsDict["mesh_dof"] = self.mesh.nodeArray - argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray - argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN - argsDict["mesh_l2g"] = self.mesh.elementNodesArray - argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] - argsDict["u_trial_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi - argsDict["u_test_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi - argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace - argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace - argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] - argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals - argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians - argsDict["nElements_global"] = self.mesh.nElements_global - argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] - argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, - argsDict["isSeepageFace"] = self.coefficients.isSeepageFace - argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] - argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] - argsDict["rho"] = self.coefficients.rho - argsDict["beta"] = self.coefficients.beta - argsDict["gravity"] = self.coefficients.gravity - argsDict["alpha"] = self.coefficients.vgm_alpha_types - argsDict["n"] = self.coefficients.vgm_n_types - argsDict["thetaR"] = self.coefficients.thetaR_types - argsDict["thetaSR"] = self.coefficients.thetaSR_types - argsDict["KWs"] = self.coefficients.Ksw_types - argsDict["useMetrics"] = 0.0 - argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf - argsDict["lag_shockCapturing"] = 0 - argsDict["shockCapturingDiffusion"] = 0.0 - argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g - argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] - argsDict["elementDiameter"] = self.mesh.elementDiametersArray - argsDict["degree_polynomial"] = degree_polynomial - argsDict["u_dof"] = self.u[0].dof - argsDict["velocity"] = self.q['velocity'] - argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] - argsDict["cfl"] = self.q[('cfl',0)] - argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] - argsDict["csrRowIndeces_u_u"] = self.csrRowIndeces[(0,0)] - argsDict["csrColumnOffsets_u_u"] = self.csrColumnOffsets[(0,0)] - argsDict["globalJacobian"] = jacobian.getCSRrepresentation()[2] - argsDict["delta_x_ij"] = self.delta_x_ij - argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global - argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray - argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray - argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray - argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] - argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] - argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] - argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] - argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] - argsDict["csrColumnOffsets_eb_u_u"] = self.csrColumnOffsets_eb[(0,0)] - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - - #arnob trying to calculate flux - #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - #Arnob trying to print flux - #argsDict["anb_seepage_flux"] = self.calculateResidual.anb_seepage_flux - - #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - #print("Hi Seepage Flux", self.coefficients.anb_seepage_flux) - #print("Hi Seepage Flux",anb_seepage_flux) - #print("The seepage is ", anb_seepage_flux) - - - - - self.calculateJacobian(argsDict) - if self.forceStrongConditions: - for dofN in list(self.dirichletConditionsForceDOF[0].DOFBoundaryConditionsDict.keys()): - global_dofN = self.offset[0]+self.stride[0]*dofN - self.nzval[np.where(self.colind == global_dofN)] = 0.0 #column - self.nzval[self.rowptr[global_dofN]:self.rowptr[global_dofN+1]] = 0.0 #row - zeroRow=True - for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]):#row - if (self.colind[i] == global_dofN): - self.nzval[i] = 1.0 - zeroRow = False - if zeroRow: - raise RuntimeError("Jacobian has a zero row because sparse matrix has no diagonal entry at row "+repr(global_dofN)+". You probably need add diagonal mass or reaction term") - #scaling = 1.0#probably want to add some scaling to match non-dirichlet diagonals in linear system - #for cj in range(self.nc): - # for dofN in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.keys()): - # global_dofN = self.offset[cj]+self.stride[cj]*dofN - # for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]): - # if (self.colind[i] == global_dofN): - # self.nzval[i] = scaling - # else: - # self.nzval[i] = 0.0 - logEvent("Jacobian ",level=10,data=jacobian) - #mwf decide if this is reasonable for solver statistics - self.nonlinear_function_jacobian_evaluations += 1 - return jacobian - def calculateElementQuadrature(self): - """ - Calculate the physical location and weights of the quadrature rules - and the shape information at the quadrature points. - - This function should be called only when the mesh changes. - """ - #self.u[0].femSpace.elementMaps.getValues(self.elementQuadraturePoints, - # self.q['x']) - self.u[0].femSpace.elementMaps.getBasisValuesRef(self.elementQuadraturePoints) - self.u[0].femSpace.elementMaps.getBasisGradientValuesRef(self.elementQuadraturePoints) - self.u[0].femSpace.getBasisValuesRef(self.elementQuadraturePoints) - self.u[0].femSpace.getBasisGradientValuesRef(self.elementQuadraturePoints) - self.coefficients.initializeElementQuadrature(self.timeIntegration.t,self.q) - if self.stabilization != None: - self.stabilization.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) - self.stabilization.initializeTimeIntegration(self.timeIntegration) - if self.shockCapturing != None: - self.shockCapturing.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) - def calculateElementBoundaryQuadrature(self): - pass - def calculateExteriorElementBoundaryQuadrature(self): - """ - Calculate the physical location and weights of the quadrature rules - and the shape information at the quadrature points on global element boundaries. - - This function should be called only when the mesh changes. - """ - # - #get physical locations of element boundary quadrature points - # - #assume all components live on the same mesh - self.u[0].femSpace.elementMaps.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.elementMaps.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.elementMaps.getValuesGlobalExteriorTrace(self.elementBoundaryQuadraturePoints, - self.ebqe['x']) - self.fluxBoundaryConditionsObjectsDict = dict([(cj,FluxBoundaryConditions(self.mesh, - self.nElementBoundaryQuadraturePoints_elementBoundary, - self.ebqe[('x')], - getAdvectiveFluxBoundaryConditions=self.advectiveFluxBoundaryConditionsSetterDict[cj], - getDiffusiveFluxBoundaryConditions=self.diffusiveFluxBoundaryConditionsSetterDictDict[cj])) - for cj in list(self.advectiveFluxBoundaryConditionsSetterDict.keys())]) - self.coefficients.initializeGlobalExteriorElementBoundaryQuadrature(self.timeIntegration.t,self.ebqe) - #argsDict = cArgumentsDict.ArgumentsDict() - #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - #print("Hi", self.coefficients.anb_seepage_flux) - - #print("The seepage is ", anb_seepage_flux) - def estimate_mt(self): - pass - def calculateSolutionAtQuadrature(self): - pass - def calculateAuxiliaryQuantitiesAfterStep(self): - pass - def postStep(self, t, firstStep=False): - with open('seepage_flux_nnnnk', "a") as f: - f.write("\n Time"+ ",\t" +"Seepage\n") - f.write(repr(t)+ ",\t" +repr(self.coefficients.anb_seepage_flux)) - - - -#argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux -#anb_seepage_flux= self.coefficients.anb_seepage_flux -#print("Hi",anb_seepage_flux) - - -#print("Hello from the python file", self.coefficients.anb_seepage_flux) diff --git a/richards_fct/richards/edit/Richards_edit.h b/richards_fct/richards/edit/Richards_edit.h deleted file mode 100755 index 36a10ac428..0000000000 --- a/richards_fct/richards/edit/Richards_edit.h +++ /dev/null @@ -1,3205 +0,0 @@ -#ifndef Richards_H -#define Richards_H -#include -#include -#include -#include "CompKernel.h" -#include "ModelFactory.h" -#include "../mprans/ArgumentsDict.h" -#include "xtensor-python/pyarray.hpp" -#define nnz nSpace - -namespace py = pybind11; -#define POWER_SMOOTHNESS_INDICATOR 2 -#define IS_BETAij_ONE 0 -#define GLOBAL_FCT 0 -namespace proteus -{ - // Power entropy // - inline double ENTROPY(const double& phi, const double& phiL, const double& phiR){ - return 1./2.*std::pow(fabs(phi),2.); - } - inline double DENTROPY(const double& phi, const double& phiL, const double& phiR){ - return fabs(phi)*(phi>=0 ? 1 : -1); - } - // Log entropy // for level set from 0 to 1 - inline double ENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ - return std::log(fabs((phi-phiL)*(phiR-phi))+1E-14); - } - inline double DENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ - return (phiL+phiR-2*phi)*((phi-phiL)*(phiR-phi)>=0 ? 1 : -1)/(fabs((phi-phiL)*(phiR-phi))+1E-14); - } -} - -namespace proteus - -{ - class Richards_base - { - //The base class defining the interface - public: - virtual ~Richards_base(){ - double anb_seepage_flux =1e-16; - } - virtual void calculateResidual(arguments_dict& args)=0; - virtual void calculateJacobian(arguments_dict& args)=0; - virtual void invert(arguments_dict& args)=0; - virtual void FCTStep(arguments_dict& args)=0; - virtual void kth_FCT_step(arguments_dict& args)=0; - virtual void calculateResidual_entropy_viscosity(arguments_dict& args)=0; - virtual void calculateMassMatrix(arguments_dict& args)=0; - }; - - template - class Richards : public Richards_base - { - public: - const int nDOF_test_X_trial_element; - CompKernelType ck; - Richards(): - nDOF_test_X_trial_element(nDOF_test_element*nDOF_trial_element), - ck() - {} - inline - void evaluateCoefficients(const int rowptr[nSpace], - const int colind[nnz], - const double rho, - const double beta, - const double gravity[nSpace], - const double alpha, - const double n_vg, - const double thetaR, - const double thetaSR, - const double KWs[nnz], - const double& u, - double& m, - double& dm, - double f[nSpace], - double df[nSpace], - double a[nnz], - double da[nnz], - double as[nnz], - double& kr, - double& dkr) - { - const int nSpace2 = nSpace * nSpace; - double psiC; - double pcBar; - double pcBar_n; - double pcBar_nM1; - double pcBar_nM2; - double onePlus_pcBar_n; - double sBar; - double sqrt_sBar; - double DsBar_DpsiC; - double thetaW; - double DthetaW_DpsiC; - double vBar; - double vBar2; - double DvBar_DpsiC; - double KWr; - double DKWr_DpsiC; - double rho2 = rho * rho; - double thetaS; - double rhom; - double drhom; - double m_vg; - double pcBarStar; - double sqrt_sBarStar; - - psiC = -u; - m_vg = 1.0 - 1.0 / n_vg; - thetaS = thetaR + thetaSR; - //std::cout<< "Thetas"< 0.0) - { - pcBar = alpha * psiC; - pcBarStar = pcBar; - if (pcBar < 1.0e-8) - pcBarStar = 1.0e-8; - pcBar_nM2 = pow(pcBarStar, n_vg - 2); - pcBar_nM1 = pcBar_nM2 * pcBar; - pcBar_n = pcBar_nM1 * pcBar; - onePlus_pcBar_n = 1.0 + pcBar_n; - - sBar = pow(onePlus_pcBar_n, -m_vg); - /* using -mn = 1-n */ - DsBar_DpsiC = alpha * (1.0 - n_vg) * (sBar/onePlus_pcBar_n)*pcBar_nM1; - - vBar = 1.0-pcBar_nM1*sBar; - vBar2 = vBar*vBar; - DvBar_DpsiC = -alpha*(n_vg-1.0)*pcBar_nM2*sBar - pcBar_nM1*DsBar_DpsiC; - - thetaW = thetaSR*sBar + thetaR; - DthetaW_DpsiC = thetaSR * DsBar_DpsiC; - - sqrt_sBar = sqrt(sBar); - sqrt_sBarStar = sqrt_sBar; - if (sqrt_sBar < 1.0e-8) - sqrt_sBarStar = 1.0e-8; - KWr= sqrt_sBar*vBar2; - DKWr_DpsiC= ((0.5/sqrt_sBarStar)*DsBar_DpsiC*vBar2 - + - 2.0*sqrt_sBar*vBar*DvBar_DpsiC); - } - else - { - thetaW = thetaS; - DthetaW_DpsiC = 0.0; - KWr = 1.0; - DKWr_DpsiC = 0.0; - } - //slight compressibility - rhom = rho*exp(beta*u); - drhom = beta*rhom; - m = rhom*thetaW; - dm = -rhom*DthetaW_DpsiC+drhom*thetaW; - for (int I=0;I thetaS || thetaW <= thetaR) - { - //cek debug - std::cout<<"rho "< 0.0) - { - isDOFBoundary = 1; - bc_u = bc_u_seepage; - } - else - { - isDOFBoundary = 0; - flux = 0.0; - } - } - /* //set DOF flag and flux correctly if seepage face */ - /* if (isSeepageFace) */ - /* { */ - /* if (flux < 0.0 || u < bc_u_seepage) */ - /* { */ - /* isDOFBoundary = 0; */ - /* flux = 0.0; */ - /* } */ - /* else */ - /* { */ - /* isDOFBoundary = 1; */ - /* bc_u = bc_u_seepage; */ - /* } */ - /* } */ - /* //Dirichlet penalty */ - /* if (isDOFBoundary) */ - /* flux += penalty*(u-bc_u); */ - } - else - flux = bc_flux; - } - - void exteriorNumericalFluxJacobian(const int rowptr[nSpace], - const int colind[nnz], - const int isDOFBoundary, - const double n[nSpace], - const double K[nnz], - const double dK[nnz], - const double grad_psi[nSpace], - const double grad_v[nSpace], - const double dK_rho_g[nSpace], - const double v, - const double penalty, - double& fluxJacobian) - { - if (isDOFBoundary) - { - fluxJacobian = 0.0; - for(int I=0;I& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - double sc_uref = args.scalar("sc_uref"); - double sc_alpha = args.scalar("sc_alpha"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& u_dof_old = args.array("u_dof_old"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m = args.array("q_m"); - xt::pyarray& q_u = args.array("q_u"); - xt::pyarray& q_dV = args.array("q_dV"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - int offset_u = args.scalar("offset_u"); - int stride_u = args.scalar("stride_u"); - xt::pyarray& globalResidual = args.array("globalResidual"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& ebqe_phi = args.array("ebqe_phi"); - double epsFact = args.scalar("epsFact"); - xt::pyarray& ebqe_u = args.array("ebqe_u"); - xt::pyarray& ebqe_flux = args.array("ebqe_flux"); - // PARAMETERS FOR EDGE BASED STABILIZATION - double cE = args.scalar("cE"); - double cK = args.scalar("cK"); - // PARAMETERS FOR LOG BASED ENTROPY FUNCTION - double uL = args.scalar("uL"); - double uR = args.scalar("uR"); - // PARAMETERS FOR EDGE VISCOSITY - int numDOFs = args.scalar("numDOFs"); - int NNZ = args.scalar("NNZ"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); - xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); - xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); - xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); - // C matrices - xt::pyarray& Cx = args.array("Cx"); - xt::pyarray& Cy = args.array("Cy"); - xt::pyarray& Cz = args.array("Cz"); - xt::pyarray& CTx = args.array("CTx"); - xt::pyarray& CTy = args.array("CTy"); - xt::pyarray& CTz = args.array("CTz"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); - int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); - // FOR FCT - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& fluxMatrix = args.array("fluxMatrix"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); - xt::pyarray& min_s_bc = args.array("min_s_bc"); - xt::pyarray& max_s_bc = args.array("max_s_bc"); - // AUX QUANTITIES OF INTEREST - xt::pyarray& quantDOFs = args.array("quantDOFs"); - xt::pyarray& sLow = args.array("sLow"); - xt::pyarray& sn = args.array("sn"); - - assert(a_rowptr.data()[nSpace] == nnz); - assert(a_rowptr.data()[nSpace] == nSpace); - //cek should this be read in? - double Ct_sge = 4.0; - //For flux Calculation - //double anb_seepage_flux=0.0; - //anb_seepage_flux = args["anb_seepage_flux"]; - //double anb_seepage_flux = args.scalar("anb_seepage_flux"); - //anb_seepage_flux=0.0; - - xt::pyarray& anb_seepage_flux_n = args.array("anb_seepage_flux_n"); - - - //double anb_seepage_flux=0.0; - double & anb_seepage_flux (args.scalar("anb_seepage_flux")) ; - //double anb_seepage_flux = args.scalar("anb_seepage_flux_n"); - - //double anb_seepage_flux=0.0; - anb_seepage_flux=0.0; - - //loop over elements to compute volume integrals and load them into element and global residual - // - //eN is the element index - //eN_k is the quadrature point index for a scalar - //eN_k_nSpace is the quadrature point index for a vector - //eN_i is the element test function index - //eN_j is the element trial function index - //eN_k_j is the quadrature point index for a trial function - //eN_k_i is the quadrature point index for a trial function - for(int eN=0;eN0) - { - std::cout<<"The seepage flux is "<& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); - xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); - xt::pyarray& globalJacobian = args.array("globalJacobian"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - assert(a_rowptr.data()[nSpace] == nnz); - assert(a_rowptr.data()[nSpace] == nSpace); - double Ct_sge = 4.0; - - - // - //loop over elements to compute volume integrals and load them into the element Jacobians and global Jacobian - // - for(int eN=0;eN& bc_mask = args.array("bc_mask"); - int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern - int numDOFs = args.scalar("numDOFs"); //number of DOFs - double dt = args.scalar("dt"); - xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) - xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn - xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn - xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& limited_solution = args.array("limited_solution"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets - xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices - xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 - xt::pyarray& max_s_bc = args.array("max_s_bc"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int MONOLITHIC = args.scalar("MONOLITHIC"); - register double Rpos[numDOFs], Rneg[numDOFs]; - register double FluxCorrectionMatrix[NNZ]; - register double solL[numDOFs]; - register double sdot[numDOFs]; - ////////////////// - // LOOP in DOFs // - ////////////////// - int ij=0; - for (int i=0; i 0) ? 1. : 0.); - Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); - - //update ij - ij+=1; - //std::cout<<"sdoti error"<0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])) - * FluxCorrectionMatrix[ij]; - alpha_dot = fmin(1.0, beta_ij*fabs(alpha_fA)/MassMatrix.data()[ij]/fmax(1.0e-8,fabs(sdoti-sdotj))); - if (MONOLITHIC == 0) - { - ith_Limiter_times_FluxCorrectionMatrix += alpha_fA; - } - else - { - ith_Limiter_times_FluxCorrectionMatrix += alpha_fA + (LUMPED_MASS_MATRIX == 1 ? 0. : 1.)*dt*alpha_dot*MassMatrix.data()[ij]*(sdoti-sdotj); - } - //update ij - ij+=1; - } - limited_solution.data()[i] = solL[i] + 1./lumped_mass_matrix.data()[i]*ith_Limiter_times_FluxCorrectionMatrix*bc_mask[i]; - } - } - - void kth_FCT_step(arguments_dict& args) - { - int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern - int numDOFs = args.scalar("numDOFs"); //number of DOFs - int num_fct_iter = args.scalar("num_fct_iter"); - double dt = args.scalar("dt"); - xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) - xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn - xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn - xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& solLim = args.array("limited_solution"); - xt::pyarray& MC = args.array("MC"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& FluxMatrix = args.array("FluxMatrix"); - xt::pyarray& limitedFlux = args.array("limited_Flux"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets - xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices - xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 - xt::pyarray& max_s_bc = args.array("max_s_bc"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int MONOLITHIC = args.scalar("MONOLITHIC"); - register double Rpos[numDOFs], Rneg[numDOFs]; - int ij=0; - - ////////////////////////////////////////////////////// - // ********** COMPUTE LOW ORDER SOLUTION ********** // - ////////////////////////////////////////////////////// - if (num_fct_iter == 0) - { // No FCT for global bounds - for (int i=0; i 0) ? 1. : 0.); - // update ij - ij+=1; - } - // compute Q vectors - double mi = ML.data()[i]; - double solLimi = solLim.data()[i]; - double Qposi = mi*(maxi-solLimi); - // compute R vectors - Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - } - ij=0; - for (int i=0; i0 ? Rposi : Rpos[j]); - // compute limited flux - ith_Limiter_times_FluxCorrectionMatrix += Lij*Fluxij; - - // update limited flux - limitedFlux.data()[ij] = Lij*Fluxij; - - //update FluxMatrix - FluxMatrix.data()[ij] = Fluxij; - - //update ij - ij+=1; - } - //update limited solution - double mi = ML.data()[i]; - solLim.data()[i] += 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; - } - } - } - - // ***************************************** // - // ********** HIGH ORDER SOLUTION ********** // - // ***************************************** // - ij=0; - for (int i=0; i 0 ? 1. : 0.); - Pnegi += fij * (fij < 0 ? 1. : 0.); - //update ij - ij+=1; - } - // compute Q vectors // - double mi = ML.data()[i]; - double Qposi = mi*(maxi-solLim.data()[i]); - double Qnegi = mi*(mini-solLim.data()[i]); - // compute R vectors // - Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); - } - - // COMPUTE LIMITERS // - ij=0; - for (int i=0; i 0 ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j]); - // compute ith_limited_flux_correction - ith_limited_flux_correction += Lij*fij; - ij+=1; - } - double mi = ML.data()[i]; - solLim[i] += 1./mi*ith_limited_flux_correction; - } - } - - void calculateResidual_entropy_viscosity(arguments_dict& args) - { - xt::pyarray& globalJacobian = args.array("globalJacobian"); - double Theta = args.scalar("Theta"); - xt::pyarray& bc_mask = args.array("bc_mask"); - double dt = args.scalar("dt"); - xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - double sc_uref = args.scalar("sc_uref"); - double sc_alpha = args.scalar("sc_alpha"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& r_l2g = args.array("r_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - int degree_polynomial = args.scalar("degree_polynomial"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& u_dof_old = args.array("u_dof_old"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m = args.array("q_m"); - xt::pyarray& q_u = args.array("q_u"); - xt::pyarray& q_dV = args.array("q_dV"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - int offset_u = args.scalar("offset_u"); - int stride_u = args.scalar("stride_u"); - xt::pyarray& globalResidual = args.array("globalResidual"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& ebqe_phi = args.array("ebqe_phi"); - double epsFact = args.scalar("epsFact"); - xt::pyarray& ebqe_u = args.array("ebqe_u"); - xt::pyarray& ebqe_flux = args.array("ebqe_flux"); - // PARAMETERS FOR EDGE BASED STABILIZATION - double cE = args.scalar("cE"); - double cK = args.scalar("cK"); - // PARAMETERS FOR LOG BASED ENTROPY FUNCTION - double uL = args.scalar("uL"); - double uR = args.scalar("uR"); - // PARAMETERS FOR EDGE VISCOSITY - int numDOFs = args.scalar("numDOFs"); - int NNZ = args.scalar("NNZ"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); - xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); - xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); - xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); - // C matrices - xt::pyarray& Cx = args.array("Cx"); - xt::pyarray& Cy = args.array("Cy"); - xt::pyarray& Cz = args.array("Cz"); - xt::pyarray& CTx = args.array("CTx"); - xt::pyarray& CTy = args.array("CTy"); - xt::pyarray& CTz = args.array("CTz"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); - int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); - // FOR FCT - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& fluxMatrix = args.array("fluxMatrix"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); - xt::pyarray& min_s_bc = args.array("min_s_bc"); - xt::pyarray& max_s_bc = args.array("max_s_bc"); - // AUX QUANTITIES OF INTEREST - xt::pyarray& quantDOFs = args.array("quantDOFs"); - xt::pyarray& sLow = args.array("sLow"); - xt::pyarray& sn = args.array("sn"); - - xt::pyarray& anb_seepage_flux_n = args.array("anb_seepage_flux_n"); - - - //double anb_seepage_flux=0.0; - double & anb_seepage_flux (args.scalar("anb_seepage_flux")) ; - //double anb_seepage_flux = args.scalar("anb_seepage_flux_n"); - - //double anb_seepage_flux=0.0; - anb_seepage_flux=0.0; - - - register double Rpos[numDOFs], Rneg[numDOFs]; - //register double FluxCorrectionMatrix[NNZ]; - // NOTE: This function follows a different (but equivalent) implementation of the smoothness based indicator than NCLS.h - // Allocate space for the transport matrices - // This is used for first order KUZMIN'S METHOD - register double TransportMatrix[NNZ],TransportMatrixConsistent[NNZ]; - register double TransportMatrixn[NNZ],TransportMatrixConsistentn[NNZ]; - std::valarray u_free_dof(numDOFs); - std::valarray u_free_dof_old(numDOFs); - std::valarray ML2(numDOFs); - - - for(int eN=0;eN0) - { - std::cout<<"The seepage flux is "<("anb_seepage_flux_n"); - //anb_seepage_flux_n=0.0; - - //anb_seepage_flux_n= anb_seepage_flux; - - - - //if (isSeepageFace) - //{ - // anb_seepage_flux+= dS* flux_ext; - // std::cout<<"The seepage flux is "<0){ - // std::cout<<"The seepage flux is "<= 0 && isFluxBoundary_u[ebNE_kb] != 1 ) //outflow. This is handled via the transport matrices. Then flux_ext=0 and dflux_ext!=0 - // { - // dflux_ext = flow; - // flux_ext = 0; - // // save external u - // ebqe_u[ebNE_kb] = u_ext; - // } - //else // inflow. This is handled via the boundary integral. Then flux_ext!=0 and dflux_ext=0 - //{ - //dflux_ext = 0; - // save external u - //ebqe_u[ebNE_kb] = isDOFBoundary_u[ebNE_kb]*ebqe_bc_u_ext[ebNE_kb]+(1-isDOFBoundary_u[ebNE_kb])*u_ext; - //if (isDOFBoundary_u[ebNE_kb] == 1) - // flux_ext = ebqe_bc_u_ext[ebNE_kb]*flow; - //else if (isFluxBoundary_u[ebNE_kb] == 1) - //flux_ext = ebqe_bc_flux_u_ext[ebNE_kb]; - // flux_ext = ebqe_bc_u_ext[ebNE_kb]; - //else - // { - // std::cout<<"warning: VOF open boundary with no external trace, setting to zero for inflow"<= 0.) - { - alpha_numerator_pos += alpha_num; - alpha_denominator_pos += alpha_num; - } - else - { - alpha_numerator_neg += alpha_num; - alpha_denominator_neg += fabs(alpha_num); - } - //update ij - ij+=1; - } - // scale g vector by lumped mass matrix - if (fabs(ML.data()[i] - ML2[i]) > 1.0e-16) - std::cout<<"ML "< 0.0) - // assert( (xi[I] - xj[I]) == delta_x_ij[offset*3+I]); - //gi_times_x += gi[I]*(xi[I]-xj[I]); - gi_times_x += gi[I]*delta_x_ij.data()[offset*3+I]; - } - // compute the positive and negative part of gi*(xi-xj) - SumPos += gi_times_x > 0 ? gi_times_x : 0; - SumNeg += gi_times_x < 0 ? gi_times_x : 0; - } - double sigmaPosi = fmin(1.,(fabs(SumNeg)+1E-15)/(SumPos+1E-15)); - double sigmaNegi = fmin(1.,(SumPos+1E-15)/(fabs(SumNeg)+1E-15)); - double alpha_numi = fabs(sigmaPosi*alpha_numerator_pos + sigmaNegi*alpha_numerator_neg); - double alpha_deni = sigmaPosi*alpha_denominator_pos + sigmaNegi*alpha_denominator_neg; - if (IS_BETAij_ONE == 1) - { - alpha_numi = fabs(alpha_numerator_pos + alpha_numerator_neg); - alpha_deni = alpha_denominator_pos + alpha_denominator_neg; - } - double alphai = alpha_numi/(alpha_deni+1E-15); - quantDOFs.data()[i] = alphai; - - if (POWER_SMOOTHNESS_INDICATOR==0) - psi[i] = 1.0; - else - psi[i] = std::pow(alphai,POWER_SMOOTHNESS_INDICATOR); //NOTE: they use alpha^2 in the paper - } - ///////////////////////////////////////////// - // ** LOOP IN DOFs FOR EDGE BASED TERMS ** // - ///////////////////////////////////////////// - ij=0; - for (int i=0; i Dissipation matrices as well. - double soli = u_free_dof[i]; // solution at time tn for the ith DOF - double solni = u_free_dof_old[i]; // solution at time tn for the ith DOF - for (int I=0;I mMax) - { - std::cout<<"mass out of bounds "< 0) ? 1. : 0.); - // Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); - // ij+=1; - // } - // double mi = ML[i]; - // double solni = u_dof_old[i]; - // double Qposi = mi*(maxi-solni); - // double Qnegi = mi*(mini-solni); - - //std::cout << Qposi << std::endl; - // Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - // Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); - - //if (Rpos[i] < 0) - //{ - // std::cout << mi << "\t" << maxi << "\t" << solni << std::endl; - // std::cout << Qposi << "\t" << Pposi << std::endl; - // std::cout << Rpos[i] << std::endl; - //abort(); - //} - //} - - //ij=0; - //for (int i=0; i 1.0 || Rposi < 0.0) - //std::cout << "Rposi: " << Rposi << std::endl; - //if (Rnegi > 1.0 || Rnegi < 0.0) - //std::cout << "Rnegi: " << Rnegi << std::endl; - - // LOOP OVER THE SPARSITY PATTERN (j-LOOP)// - // for (int offset=csrRowIndeces_DofLoops.data()[i]; - // offset0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])); - // //Lij=0.0; - // ith_Limiter_times_FluxCorrectionMatrix += Lij*FluxCorrectionMatrix[ij]; - // //update ij - // ij+=1; - // } - // double mi = ML[i]; - // double solni = u_dof_old[i]; - // globalResidual[i] = solni + 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; - //} - } - - - void invert(arguments_dict& args) - { - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - xt::pyarray& globalResidual = args.array("globalResidual"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - int numDOFs = args.scalar("numDOFs"); - for (int i=0; i mMax) - { - std::cout<<"mass out of bounds "<("dt"); - xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - //element boundary - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - //physics - int nElements_global = args.scalar("nElements_global"); - //new - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - //end new - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& r_l2g = args.array("r_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - int degree_polynomial = args.scalar("degree_polynomial"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); - xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); - xt::pyarray& globalJacobian = args.array("globalJacobian"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - //std::cout<<"ndjaco address "<(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - else if (nSpaceIn == 2) - return proteus::chooseAndAllocateDiscretization2D(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - else - { - assert(nSpaceIn == 3); - return proteus::chooseAndAllocateDiscretization(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - } - } -};//proteus -#endif \ No newline at end of file diff --git a/richards_fct/richards/edit/Richards_edit_n.h b/richards_fct/richards/edit/Richards_edit_n.h deleted file mode 100644 index 789cf629e3..0000000000 --- a/richards_fct/richards/edit/Richards_edit_n.h +++ /dev/null @@ -1,3342 +0,0 @@ -#ifndef Richards_H -#define Richards_H -#include -#include -#include -#include "CompKernel.h" -#include "ModelFactory.h" -#include "../mprans/ArgumentsDict.h" -#include "xtensor-python/pyarray.hpp" -#define nnz nSpace - -namespace py = pybind11; -#define POWER_SMOOTHNESS_INDICATOR 2 -#define IS_BETAij_ONE 0 -#define GLOBAL_FCT 0 -namespace proteus -{ - // Power entropy // - inline double ENTROPY(const double& phi, const double& phiL, const double& phiR){ - return 1./2.*std::pow(fabs(phi),2.); - } - inline double DENTROPY(const double& phi, const double& phiL, const double& phiR){ - return fabs(phi)*(phi>=0 ? 1 : -1); - } - // Log entropy // for level set from 0 to 1 - inline double ENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ - return std::log(fabs((phi-phiL)*(phiR-phi))+1E-14); - } - inline double DENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ - return (phiL+phiR-2*phi)*((phi-phiL)*(phiR-phi)>=0 ? 1 : -1)/(fabs((phi-phiL)*(phiR-phi))+1E-14); - } -} - -namespace proteus - -{ - class Richards_base - { - //The base class defining the interface - public: - virtual ~Richards_base(){ - double anb_seepage_flux =1e-16; - } - virtual void calculateResidual(arguments_dict& args)=0; - virtual void calculateJacobian(arguments_dict& args)=0; - virtual void invert(arguments_dict& args)=0; - virtual void FCTStep(arguments_dict& args)=0; - virtual void kth_FCT_step(arguments_dict& args)=0; - virtual void calculateResidual_entropy_viscosity(arguments_dict& args)=0; - virtual void calculateMassMatrix(arguments_dict& args)=0; - }; - - template - class Richards : public Richards_base - { - public: - const int nDOF_test_X_trial_element; - CompKernelType ck; - Richards(): - nDOF_test_X_trial_element(nDOF_test_element*nDOF_trial_element), - ck() - {} - inline - void evaluateCoefficients(const int rowptr[nSpace], - const int colind[nnz], - const double rho, - const double beta, - const double gravity[nSpace], - const double alpha, - const double n_vg, - const double thetaR, - const double thetaSR, - const double KWs[nnz], - const double& u, - double& m, - double& dm, - double f[nSpace], - double df[nSpace], - double a[nnz], - double da[nnz], - double as[nnz], - double& kr, - double& dkr) - { - const int nSpace2 = nSpace * nSpace; - double psiC; - double pcBar; - double pcBar_n; - double pcBar_nM1; - double pcBar_nM2; - double onePlus_pcBar_n; - double sBar; - double sqrt_sBar; - double DsBar_DpsiC; - double thetaW; - double DthetaW_DpsiC; - double vBar; - double vBar2; - double DvBar_DpsiC; - double KWr; - double DKWr_DpsiC; - double rho2 = rho * rho; - double thetaS; - double rhom; - double drhom; - double m_vg; - double pcBarStar; - double sqrt_sBarStar; - - psiC = -u; - m_vg = 1.0 - 1.0 / n_vg; - thetaS = thetaR + thetaSR; - //std::cout<< "Thetas"< 0.0) - { - pcBar = alpha * psiC; - pcBarStar = pcBar; - if (pcBar < 1.0e-8) - pcBarStar = 1.0e-8; - pcBar_nM2 = pow(pcBarStar, n_vg - 2); - pcBar_nM1 = pcBar_nM2 * pcBar; - pcBar_n = pcBar_nM1 * pcBar; - onePlus_pcBar_n = 1.0 + pcBar_n; - - sBar = pow(onePlus_pcBar_n, -m_vg); - /* using -mn = 1-n */ - DsBar_DpsiC = alpha * (1.0 - n_vg) * (sBar/onePlus_pcBar_n)*pcBar_nM1; - - vBar = 1.0-pcBar_nM1*sBar; - vBar2 = vBar*vBar; - DvBar_DpsiC = -alpha*(n_vg-1.0)*pcBar_nM2*sBar - pcBar_nM1*DsBar_DpsiC; - - thetaW = thetaSR*sBar + thetaR; - DthetaW_DpsiC = thetaSR * DsBar_DpsiC; - - sqrt_sBar = sqrt(sBar); - sqrt_sBarStar = sqrt_sBar; - if (sqrt_sBar < 1.0e-8) - sqrt_sBarStar = 1.0e-8; - KWr= sqrt_sBar*vBar2; - DKWr_DpsiC= ((0.5/sqrt_sBarStar)*DsBar_DpsiC*vBar2 - + - 2.0*sqrt_sBar*vBar*DvBar_DpsiC); - } - else - { - thetaW = thetaS; - DthetaW_DpsiC = 0.0; - KWr = 1.0; - DKWr_DpsiC = 0.0; - } - //slight compressibility - rhom = rho*exp(beta*u); - drhom = beta*rhom; - m = rhom*thetaW; - dm = -rhom*DthetaW_DpsiC+drhom*thetaW; - for (int I=0;I thetaS || thetaW <= thetaR) - { - //cek debug - std::cout<<"rho "< 0.0) - { - isDOFBoundary = 1; - bc_u = bc_u_seepage; - } - else - { - isDOFBoundary = 0; - flux = 0.0; - } - } - /* //set DOF flag and flux correctly if seepage face */ - /* if (isSeepageFace) */ - /* { */ - /* if (flux < 0.0 || u < bc_u_seepage) */ - /* { */ - /* isDOFBoundary = 0; */ - /* flux = 0.0; */ - /* } */ - /* else */ - /* { */ - /* isDOFBoundary = 1; */ - /* bc_u = bc_u_seepage; */ - /* } */ - /* } */ - /* //Dirichlet penalty */ - /* if (isDOFBoundary) */ - /* flux += penalty*(u-bc_u); */ - } - else - flux = bc_flux; - } - - void exteriorNumericalFluxJacobian(const int rowptr[nSpace], - const int colind[nnz], - const int isDOFBoundary, - const double n[nSpace], - const double K[nnz], - const double dK[nnz], - const double grad_psi[nSpace], - const double grad_v[nSpace], - const double dK_rho_g[nSpace], - const double v, - const double penalty, - double& fluxJacobian) - { - if (isDOFBoundary) - { - fluxJacobian = 0.0; - for(int I=0;I& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - double sc_uref = args.scalar("sc_uref"); - double sc_alpha = args.scalar("sc_alpha"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& u_dof_old = args.array("u_dof_old"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m = args.array("q_m"); - xt::pyarray& q_u = args.array("q_u"); - xt::pyarray& q_dV = args.array("q_dV"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - int offset_u = args.scalar("offset_u"); - int stride_u = args.scalar("stride_u"); - xt::pyarray& globalResidual = args.array("globalResidual"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& ebqe_phi = args.array("ebqe_phi"); - double epsFact = args.scalar("epsFact"); - xt::pyarray& ebqe_u = args.array("ebqe_u"); - xt::pyarray& ebqe_flux = args.array("ebqe_flux"); - // PARAMETERS FOR EDGE BASED STABILIZATION - double cE = args.scalar("cE"); - double cK = args.scalar("cK"); - // PARAMETERS FOR LOG BASED ENTROPY FUNCTION - double uL = args.scalar("uL"); - double uR = args.scalar("uR"); - // PARAMETERS FOR EDGE VISCOSITY - int numDOFs = args.scalar("numDOFs"); - int NNZ = args.scalar("NNZ"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); - xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); - xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); - xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); - // C matrices - xt::pyarray& Cx = args.array("Cx"); - xt::pyarray& Cy = args.array("Cy"); - xt::pyarray& Cz = args.array("Cz"); - xt::pyarray& CTx = args.array("CTx"); - xt::pyarray& CTy = args.array("CTy"); - xt::pyarray& CTz = args.array("CTz"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); - int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); - // FOR FCT - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& fluxMatrix = args.array("fluxMatrix"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); - xt::pyarray& min_s_bc = args.array("min_s_bc"); - xt::pyarray& max_s_bc = args.array("max_s_bc"); - // AUX QUANTITIES OF INTEREST - xt::pyarray& quantDOFs = args.array("quantDOFs"); - xt::pyarray& sLow = args.array("sLow"); - xt::pyarray& sn = args.array("sn"); - - assert(a_rowptr.data()[nSpace] == nnz); - assert(a_rowptr.data()[nSpace] == nSpace); - //cek should this be read in? - double Ct_sge = 4.0; - //For flux Calculation - //double anb_seepage_flux=0.0; - //anb_seepage_flux = args["anb_seepage_flux"]; - //double anb_seepage_flux = args.scalar("anb_seepage_flux"); - //anb_seepage_flux=0.0; - - xt::pyarray& anb_seepage_flux_n = args.array("anb_seepage_flux_n"); - - - //double anb_seepage_flux=0.0; - double & anb_seepage_flux (args.scalar("anb_seepage_flux")) ; - //double anb_seepage_flux = args.scalar("anb_seepage_flux_n"); - - //double anb_seepage_flux=0.0; - anb_seepage_flux=0.0; - - //loop over elements to compute volume integrals and load them into element and global residual - // - //eN is the element index - //eN_k is the quadrature point index for a scalar - //eN_k_nSpace is the quadrature point index for a vector - //eN_i is the element test function index - //eN_j is the element trial function index - //eN_k_j is the quadrature point index for a trial function - //eN_k_i is the quadrature point index for a trial function - for(int eN=0;eN0) - { - std::cout<<"The seepage flux is "<& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); - xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); - xt::pyarray& globalJacobian = args.array("globalJacobian"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - assert(a_rowptr.data()[nSpace] == nnz); - assert(a_rowptr.data()[nSpace] == nSpace); - double Ct_sge = 4.0; - - - // - //loop over elements to compute volume integrals and load them into the element Jacobians and global Jacobian - // - for(int eN=0;eN& bc_mask = args.array("bc_mask"); - int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern - int numDOFs = args.scalar("numDOFs"); //number of DOFs - double dt = args.scalar("dt"); - xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) - xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn - xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn - xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& limited_solution = args.array("limited_solution"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets - xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices - xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 - xt::pyarray& max_s_bc = args.array("max_s_bc"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int MONOLITHIC = args.scalar("MONOLITHIC"); - register double Rpos[numDOFs], Rneg[numDOFs]; - register double FluxCorrectionMatrix[NNZ]; - register double solL[numDOFs]; - register double sdot[numDOFs]; - ////////////////// - // LOOP in DOFs // - ////////////////// - int ij=0; - for (int i=0; i 0) ? 1. : 0.); - Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); - - //update ij - ij+=1; - //std::cout<<"sdoti error"<0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])) - * FluxCorrectionMatrix[ij]; - alpha_dot = fmin(1.0, beta_ij*fabs(alpha_fA)/MassMatrix.data()[ij]/fmax(1.0e-8,fabs(sdoti-sdotj))); - if (MONOLITHIC == 0) - { - ith_Limiter_times_FluxCorrectionMatrix += alpha_fA; - } - else - { - ith_Limiter_times_FluxCorrectionMatrix += alpha_fA + (LUMPED_MASS_MATRIX == 1 ? 0. : 1.)*dt*alpha_dot*MassMatrix.data()[ij]*(sdoti-sdotj); - } - //update ij - ij+=1; - } - limited_solution.data()[i] = solL[i] + 1./lumped_mass_matrix.data()[i]*ith_Limiter_times_FluxCorrectionMatrix*bc_mask[i]; - } - } - - void kth_FCT_step(arguments_dict& args) - { - int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern - int numDOFs = args.scalar("numDOFs"); //number of DOFs - int num_fct_iter = args.scalar("num_fct_iter"); - double dt = args.scalar("dt"); - xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) - xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn - xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn - xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& solLim = args.array("limited_solution"); - xt::pyarray& MC = args.array("MC"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& FluxMatrix = args.array("FluxMatrix"); - xt::pyarray& limitedFlux = args.array("limited_Flux"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets - xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices - xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 - xt::pyarray& max_s_bc = args.array("max_s_bc"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int MONOLITHIC = args.scalar("MONOLITHIC"); - register double Rpos[numDOFs], Rneg[numDOFs]; - int ij=0; - - ////////////////////////////////////////////////////// - // ********** COMPUTE LOW ORDER SOLUTION ********** // - ////////////////////////////////////////////////////// - if (num_fct_iter == 0) - { // No FCT for global bounds - for (int i=0; i 0) ? 1. : 0.); - // update ij - ij+=1; - } - // compute Q vectors - double mi = ML.data()[i]; - double solLimi = solLim.data()[i]; - double Qposi = mi*(maxi-solLimi); - // compute R vectors - Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - } - ij=0; - for (int i=0; i0 ? Rposi : Rpos[j]); - // compute limited flux - ith_Limiter_times_FluxCorrectionMatrix += Lij*Fluxij; - - // update limited flux - limitedFlux.data()[ij] = Lij*Fluxij; - - //update FluxMatrix - FluxMatrix.data()[ij] = Fluxij; - - //update ij - ij+=1; - } - //update limited solution - double mi = ML.data()[i]; - solLim.data()[i] += 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; - } - } - } - - // ***************************************** // - // ********** HIGH ORDER SOLUTION ********** // - // ***************************************** // - ij=0; - for (int i=0; i 0 ? 1. : 0.); - Pnegi += fij * (fij < 0 ? 1. : 0.); - //update ij - ij+=1; - } - // compute Q vectors // - double mi = ML.data()[i]; - double Qposi = mi*(maxi-solLim.data()[i]); - double Qnegi = mi*(mini-solLim.data()[i]); - // compute R vectors // - Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); - } - - // COMPUTE LIMITERS // - ij=0; - for (int i=0; i 0 ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j]); - // compute ith_limited_flux_correction - ith_limited_flux_correction += Lij*fij; - ij+=1; - } - double mi = ML.data()[i]; - solLim[i] += 1./mi*ith_limited_flux_correction; - } - } - - void calculateResidual_entropy_viscosity(arguments_dict& args) - { - xt::pyarray& globalJacobian = args.array("globalJacobian"); - double Theta = args.scalar("Theta"); - xt::pyarray& bc_mask = args.array("bc_mask"); - double dt = args.scalar("dt"); - xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - double sc_uref = args.scalar("sc_uref"); - double sc_alpha = args.scalar("sc_alpha"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& r_l2g = args.array("r_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - int degree_polynomial = args.scalar("degree_polynomial"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& u_dof_old = args.array("u_dof_old"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m = args.array("q_m"); - xt::pyarray& q_u = args.array("q_u"); - xt::pyarray& q_dV = args.array("q_dV"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - int offset_u = args.scalar("offset_u"); - int stride_u = args.scalar("stride_u"); - xt::pyarray& globalResidual = args.array("globalResidual"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& ebqe_phi = args.array("ebqe_phi"); - double epsFact = args.scalar("epsFact"); - xt::pyarray& ebqe_u = args.array("ebqe_u"); - xt::pyarray& ebqe_flux = args.array("ebqe_flux"); - // PARAMETERS FOR EDGE BASED STABILIZATION - double cE = args.scalar("cE"); - double cK = args.scalar("cK"); - // PARAMETERS FOR LOG BASED ENTROPY FUNCTION - double uL = args.scalar("uL"); - double uR = args.scalar("uR"); - // PARAMETERS FOR EDGE VISCOSITY - int numDOFs = args.scalar("numDOFs"); - int NNZ = args.scalar("NNZ"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); - xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); - xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); - xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); - // C matrices - xt::pyarray& Cx = args.array("Cx"); - xt::pyarray& Cy = args.array("Cy"); - xt::pyarray& Cz = args.array("Cz"); - xt::pyarray& CTx = args.array("CTx"); - xt::pyarray& CTy = args.array("CTy"); - xt::pyarray& CTz = args.array("CTz"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); - int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); - // FOR FCT - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& fluxMatrix = args.array("fluxMatrix"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); - xt::pyarray& min_s_bc = args.array("min_s_bc"); - xt::pyarray& max_s_bc = args.array("max_s_bc"); - // AUX QUANTITIES OF INTEREST - xt::pyarray& quantDOFs = args.array("quantDOFs"); - xt::pyarray& sLow = args.array("sLow"); - xt::pyarray& sn = args.array("sn"); - - xt::pyarray& anb_seepage_flux_n = args.array("anb_seepage_flux_n"); - - - //double anb_seepage_flux=0.0; - double & anb_seepage_flux (args.scalar("anb_seepage_flux")) ; - //double anb_seepage_flux = args.scalar("anb_seepage_flux_n"); - - //double anb_seepage_flux=0.0; - anb_seepage_flux=0.0; - - - register double Rpos[numDOFs], Rneg[numDOFs]; - //register double FluxCorrectionMatrix[NNZ]; - // NOTE: This function follows a different (but equivalent) implementation of the smoothness based indicator than NCLS.h - // Allocate space for the transport matrices - // This is used for first order KUZMIN'S METHOD - register double TransportMatrix[NNZ],TransportMatrixConsistent[NNZ]; - register double TransportMatrixn[NNZ],TransportMatrixConsistentn[NNZ]; - std::valarray u_free_dof(numDOFs); - std::valarray u_free_dof_old(numDOFs); - std::valarray ML2(numDOFs); - - - for(int eN=0;eN0) - { - std::cout<<"The seepage flux is "<("anb_seepage_flux_n"); - //anb_seepage_flux_n=0.0; - - //anb_seepage_flux_n= anb_seepage_flux; - - - - //if (isSeepageFace) - //{ - // anb_seepage_flux+= dS* flux_ext; - // std::cout<<"The seepage flux is "<0){ - // std::cout<<"The seepage flux is "<= 0 && isFluxBoundary_u[ebNE_kb] != 1 ) //outflow. This is handled via the transport matrices. Then flux_ext=0 and dflux_ext!=0 - // { - // dflux_ext = flow; - // flux_ext = 0; - // // save external u - // ebqe_u[ebNE_kb] = u_ext; - // } - //else // inflow. This is handled via the boundary integral. Then flux_ext!=0 and dflux_ext=0 - //{ - //dflux_ext = 0; - // save external u - //ebqe_u[ebNE_kb] = isDOFBoundary_u[ebNE_kb]*ebqe_bc_u_ext[ebNE_kb]+(1-isDOFBoundary_u[ebNE_kb])*u_ext; - //if (isDOFBoundary_u[ebNE_kb] == 1) - // flux_ext = ebqe_bc_u_ext[ebNE_kb]*flow; - //else if (isFluxBoundary_u[ebNE_kb] == 1) - //flux_ext = ebqe_bc_flux_u_ext[ebNE_kb]; - // flux_ext = ebqe_bc_u_ext[ebNE_kb]; - //else - // { - // std::cout<<"warning: VOF open boundary with no external trace, setting to zero for inflow"<= 0.) - { - alpha_numerator_pos += alpha_num; - alpha_denominator_pos += alpha_num; - } - else - { - alpha_numerator_neg += alpha_num; - alpha_denominator_neg += fabs(alpha_num); - } - //update ij - ij+=1; - } - // scale g vector by lumped mass matrix - if (fabs(ML.data()[i] - ML2[i]) > 1.0e-16) - std::cout<<"ML "< 0.0) - // assert( (xi[I] - xj[I]) == delta_x_ij[offset*3+I]); - //gi_times_x += gi[I]*(xi[I]-xj[I]); - gi_times_x += gi[I]*delta_x_ij.data()[offset*3+I]; - } - // compute the positive and negative part of gi*(xi-xj) - SumPos += gi_times_x > 0 ? gi_times_x : 0; - SumNeg += gi_times_x < 0 ? gi_times_x : 0; - } - double sigmaPosi = fmin(1.,(fabs(SumNeg)+1E-15)/(SumPos+1E-15)); - double sigmaNegi = fmin(1.,(SumPos+1E-15)/(fabs(SumNeg)+1E-15)); - double alpha_numi = fabs(sigmaPosi*alpha_numerator_pos + sigmaNegi*alpha_numerator_neg); - double alpha_deni = sigmaPosi*alpha_denominator_pos + sigmaNegi*alpha_denominator_neg; - if (IS_BETAij_ONE == 1) - { - alpha_numi = fabs(alpha_numerator_pos + alpha_numerator_neg); - alpha_deni = alpha_denominator_pos + alpha_denominator_neg; - } - double alphai = alpha_numi/(alpha_deni+1E-15); - quantDOFs.data()[i] = alphai; - - if (POWER_SMOOTHNESS_INDICATOR==0) - psi[i] = 1.0; - else - psi[i] = std::pow(alphai,POWER_SMOOTHNESS_INDICATOR); //NOTE: they use alpha^2 in the paper - } - ///////////////////////////////////////////// - // ** LOOP IN DOFs FOR EDGE BASED TERMS ** // - ///////////////////////////////////////////// - ij=0; - for (int i=0; i Dissipation matrices as well. - double soli = u_free_dof[i]; // solution at time tn for the ith DOF - double solni = u_free_dof_old[i]; // solution at time tn for the ith DOF - for (int I=0;I& bc_mask = args.array("bc_mask"); - //int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern - //int numDOFs = args.scalar("numDOFs"); //number of DOFs - //double dt = args.scalar("dt"); - //xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) - - //xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn - xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn - xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 - //xt::pyarray& uLow = args.array("uLow"); - //xt::pyarray& uDotLow = args.array("uDotLow"); - //xt::pyarray& limited_solution = args.array("limited_solution"); - //xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces - //xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets - xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix - //xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices - //xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 - //xt::pyarray& max_s_bc = args.array("max_s_bc"); - //int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - //int MONOLITHIC = args.scalar("MONOLITHIC"); - register double Rpos[numDOFs], Rneg[numDOFs]; - register double FluxCorrectionMatrix[NNZ]; - register double solL[numDOFs]; - register double sdot[numDOFs]; - - int ij=0; - for (int i=0; i 0) ? 1. : 0.); - Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); - - //update ij - ij+=1; - //std::cout<<"sdoti error"<0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])) - * FluxCorrectionMatrix[ij]; - alpha_dot = fmin(1.0, beta_ij*fabs(alpha_fA)/MassMatrix.data()[ij]/fmax(1.0e-8,fabs(sdoti-sdotj))); - - ith_Limiter_times_FluxCorrectionMatrix += alpha_fA; - //update ij - ij+=1; - } - - - //std::cout<<"Limiter "<< ith_Limiter_times_FluxCorrectionMatrix < mMax) - { - std::cout<<"mass out of bounds "< 0) ? 1. : 0.); - // Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); - // ij+=1; - // } - // double mi = ML[i]; - // double solni = u_dof_old[i]; - // double Qposi = mi*(maxi-solni); - // double Qnegi = mi*(mini-solni); - - //std::cout << Qposi << std::endl; - // Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - // Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); - - //if (Rpos[i] < 0) - //{ - // std::cout << mi << "\t" << maxi << "\t" << solni << std::endl; - // std::cout << Qposi << "\t" << Pposi << std::endl; - // std::cout << Rpos[i] << std::endl; - //abort(); - //} - } - - //ij=0; - //for (int i=0; i 1.0 || Rposi < 0.0) - //std::cout << "Rposi: " << Rposi << std::endl; - //if (Rnegi > 1.0 || Rnegi < 0.0) - //std::cout << "Rnegi: " << Rnegi << std::endl; - - // LOOP OVER THE SPARSITY PATTERN (j-LOOP)// - // for (int offset=csrRowIndeces_DofLoops.data()[i]; - // offset0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])); - // //Lij=0.0; - // ith_Limiter_times_FluxCorrectionMatrix += Lij*FluxCorrectionMatrix[ij]; - // //update ij - // ij+=1; - // } - // double mi = ML[i]; - // double solni = u_dof_old[i]; - // globalResidual[i] = solni + 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; - //} - } - - - void invert(arguments_dict& args) - { - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - xt::pyarray& globalResidual = args.array("globalResidual"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - int numDOFs = args.scalar("numDOFs"); - for (int i=0; i mMax) - { - std::cout<<"mass out of bounds "<("dt"); - xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - //element boundary - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - //physics - int nElements_global = args.scalar("nElements_global"); - //new - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - //end new - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& r_l2g = args.array("r_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - int degree_polynomial = args.scalar("degree_polynomial"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); - xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); - xt::pyarray& globalJacobian = args.array("globalJacobian"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - //std::cout<<"ndjaco address "<(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - else if (nSpaceIn == 2) - return proteus::chooseAndAllocateDiscretization2D(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - else - { - assert(nSpaceIn == 3); - return proteus::chooseAndAllocateDiscretization(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - } - } -};//proteus -#endif \ No newline at end of file diff --git a/richards_fct/richards/edit/Richards_edit_n.py b/richards_fct/richards/edit/Richards_edit_n.py deleted file mode 100644 index b299d490ce..0000000000 --- a/richards_fct/richards/edit/Richards_edit_n.py +++ /dev/null @@ -1,1873 +0,0 @@ -from __future__ import division -from builtins import range -from past.utils import old_div -import proteus -from .cRichards import * -import numpy as np -from proteus.Transport import OneLevelTransport -from proteus.Transport import TC_base, NonlinearEquation, logEvent, memory -from proteus.Transport import FluxBoundaryConditions, Comm, cfemIntegrals -from proteus.Transport import DOFBoundaryConditions, Quadrature -from proteus.mprans import cArgumentsDict -from proteus.LinearAlgebraTools import SparseMat -from proteus import TimeIntegration -from proteus.NonlinearSolvers import ExplicitLumpedMassMatrixForRichards -from proteus.NonlinearSolvers import Newton - - -class ThetaScheme(TimeIntegration.BackwardEuler): - def __init__(self,transport,integrateInterpolationPoints=False): - self.transport=transport - TimeIntegration.BackwardEuler.__init__(self,transport, integrateInterpolationPoints) - def updateTimeHistory(self,resetFromDOF=False): - TimeIntegration.BackwardEuler.updateTimeHistory(self,resetFromDOF) - self.transport.u_dof_old[:] = self.u -class RKEV(TimeIntegration.SSP): - from proteus import TimeIntegration - """ - Wrapper for SSPRK time integration using EV - - ... more to come ... - """ - - def __init__(self, transport, timeOrder=1, runCFL=0.1, integrateInterpolationPoints=False): - TimeIntegration.SSP.__init__(self, transport, integrateInterpolationPoints=integrateInterpolationPoints) - self.runCFL = runCFL - self.dtLast = None - self.isAdaptive = True - # About the cfl - assert transport.coefficients.STABILIZATION_TYPE > 0, "SSP method just works for edge based EV methods; i.e., STABILIZATION_TYPE>0" - assert hasattr(transport, 'edge_based_cfl'), "No edge based cfl defined" - self.cfl = transport.edge_based_cfl - # Stuff particular for SSP - self.timeOrder = timeOrder # order of approximation - self.nStages = timeOrder # number of stages total - self.lstage = 0 # last stage completed - # storage vectors - self.u_dof_last = {} - # per component stage values, list with array at each stage - self.u_dof_stage = {} - for ci in range(self.nc): - if ('m', ci) in transport.q: - self.u_dof_last[ci] = transport.u[ci].dof.copy() - self.u_dof_stage[ci] = [] - for k in range(self.nStages + 1): - self.u_dof_stage[ci].append(transport.u[ci].dof.copy()) - #print() - - - # def set_dt(self, DTSET): - # self.dt = DTSET # don't update t - def choose_dt(self): - comm = Comm.get() - maxCFL = 1.0e-6 - maxCFL = max(maxCFL, comm.globalMax(self.cfl.max())) - self.dt = old_div(self.runCFL, maxCFL) - if self.dtLast is None: - self.dtLast = self.dt - self.t = self.tLast + self.dt - self.substeps = [self.t for i in range(self.nStages)] # Manuel is ignoring different time step levels for now - #print("Hi, This is Arnob") - - - def initialize_dt(self, t0, tOut, q): - """ - Modify self.dt - """ - self.tLast = t0 - self.choose_dt() - self.t = t0 + self.dt - - def setCoefficients(self): - """ - beta are all 1's here - mwf not used right now - """ - self.alpha = np.zeros((self.nStages, self.nStages), 'd') - self.dcoefs = np.zeros((self.nStages), 'd') - - def updateStage(self): - """ - Need to switch to use coefficients - """ - self.lstage += 1 - assert self.timeOrder in [1, 2, 3] - assert self.lstage > 0 and self.lstage <= self.timeOrder - if self.timeOrder == 3: - if self.lstage == 1: - logEvent("First stage of SSP33 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - # update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] - elif self.lstage == 2: - logEvent("Second stage of SSP33 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - self.u_dof_stage[ci][self.lstage] *= old_div(1., 4.) - self.u_dof_stage[ci][self.lstage] += 3. / 4. * self.u_dof_last[ci] - # Update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] - elif self.lstage == 3: - logEvent("Third stage of SSP33 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - self.u_dof_stage[ci][self.lstage] *= old_div(2.0, 3.0) - self.u_dof_stage[ci][self.lstage] += 1.0 / 3.0 * self.u_dof_last[ci] - # update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_last[ci] - # update solution to u[0].dof - self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] - elif self.timeOrder == 2: - if self.lstage == 1: - logEvent("First stage of SSP22 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - # Update u_dof_old - self.transport.u_dof_old[:] = self.transport.u[ci].dof - elif self.lstage == 2: - logEvent("Second stage of SSP22 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - self.u_dof_stage[ci][self.lstage][:] *= old_div(1., 2.) - self.u_dof_stage[ci][self.lstage][:] += 1. / 2. * self.u_dof_last[ci] - # update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_last[ci] - # update solution to u[0].dof - self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] - else: - assert self.timeOrder == 1 - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof[:] - self.transport.u_dof_old[:] = self.transport.u[ci].dof - #self.print("Hi, Arnob") - - def initializeTimeHistory(self, resetFromDOF=True): - """ - Push necessary information into time history arrays - """ - for ci in range(self.nc): - self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] - for k in range(self.nStages): - self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] - - def updateTimeHistory(self, resetFromDOF=False): - """ - assumes successful step has been taken - """ - - self.t = self.tLast + self.dt - for ci in range(self.nc): - self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] - for k in range(self.nStages): - self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] - self.lstage = 0 - self.dtLast = self.dt - self.tLast = self.t - - def generateSubsteps(self, tList): - """ - create list of substeps over time values given in tList. These correspond to stages - """ - self.substeps = [] - tLast = self.tLast - for t in tList: - dttmp = t - tLast - self.substeps.extend([tLast + dttmp for i in range(self.nStages)]) - tLast = t - - def resetOrder(self, order): - """ - initialize data structures for stage updges - """ - self.timeOrder = order # order of approximation - self.nStages = order # number of stages total - self.lstage = 0 # last stage completed - # storage vectors - # per component stage values, list with array at each stage - self.u_dof_stage = {} - for ci in range(self.nc): - if ('m', ci) in self.transport.q: - self.u_dof_stage[ci] = [] - for k in range(self.nStages + 1): - self.u_dof_stage[ci].append(self.transport.u[ci].dof.copy()) - self.substeps = [self.t for i in range(self.nStages)] - - def setFromOptions(self, nOptions): - """ - allow classes to set various numerical parameters - """ - if 'runCFL' in dir(nOptions): - self.runCFL = nOptions.runCFL - flags = ['timeOrder'] - for flag in flags: - if flag in dir(nOptions): - val = getattr(nOptions, flag) - setattr(self, flag, val) - if flag == 'timeOrder': - self.resetOrder(self.timeOrder) - - - -class Coefficients(proteus.TransportCoefficients.TC_base): - """ - version of Re where element material type id's used in evals - """ - from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2 - from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchten_sd_het - def __init__(self, - nd, - Ksw_types, - vgm_n_types, - vgm_alpha_types, - thetaR_types, - thetaSR_types, - gravity, - density, - beta, - diagonal_conductivity=True, - getSeepageFace=None, - # FOR EDGE BASED EV - STABILIZATION_TYPE=0, - ENTROPY_TYPE=2, # logarithmic - LUMPED_MASS_MATRIX=False, - MONOLITHIC=True, - FCT=True, - num_fct_iter=1, - # FOR ENTROPY VISCOSITY - cE=1.0, - uL=0.0, - uR=1.0, - # FOR ARTIFICIAL COMPRESSION - cK=1.0, - # OUTPUT quantDOFs - outputQuantDOFs=False, ): - self.anb_seepage_flux= 0.00 - #self.anb_seepage_flux_n =0.0 - variableNames=['pressure_head'] - nc=1 - mass={0:{0:'nonlinear'}} - advection={0:{0:'nonlinear'}} - diffusion={0:{0:{0:'nonlinear'}}} - potential={0:{0:'u'}} - reaction={0:{0:'linear'}} - hamiltonian={} - self.getSeepageFace=getSeepageFace - self.gravity=gravity - self.rho = density - self.beta=beta - self.vgm_n_types = vgm_n_types - self.vgm_alpha_types = vgm_alpha_types - self.thetaR_types = thetaR_types - self.thetaSR_types = thetaSR_types - self.elementMaterialTypes = None - self.exteriorElementBoundaryTypes = None - self.materialTypes_q = None - self.materialTypes_ebq = None - self.materialTypes_ebqe = None - self.nd = nd - self.nMaterialTypes = len(thetaR_types) - self.q = {}; self.ebqe = {}; self.ebq = {}; self.ebq_global={} - #try to allow some flexibility in input of permeability/conductivity tensor - self.diagonal_conductivity = diagonal_conductivity - self.Ksw_types_in = Ksw_types - if self.diagonal_conductivity: - sparseDiffusionTensors = {(0,0):(np.arange(self.nd+1,dtype='i'), - np.arange(self.nd,dtype='i'))} - - assert len(Ksw_types.shape) in [1,2], "if diagonal conductivity true then Ksw_types scalar or vector of diagonal entries" - #allow scalar input Ks - if len(Ksw_types.shape)==1: - self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd),'d') - for I in range(self.nd): - self.Ksw_types[:,I] = Ksw_types - else: - self.Ksw_types = Ksw_types - else: #full - sparseDiffusionTensors = {(0,0):(np.arange(self.nd**2+1,step=self.nd,dtype='i'), - np.array([list(range(self.nd)) for row in range(self.nd)],dtype='i'))} - assert len(Ksw_types.shape) in [1,2], "if full tensor conductivity true then Ksw_types scalar or 'flattened' row-major representation of entries" - if len(Ksw_types.shape)==1: - self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd**2),'d') - for I in range(self.nd): - self.Ksw_types[:,I*self.nd+I] = Ksw_types - else: - assert Ksw_types.shape[1] == self.nd**2 - self.Ksw_types = Ksw_types - # EDGE BASED (AND ENTROPY) VISCOSITY - self.LUMPED_MASS_MATRIX = LUMPED_MASS_MATRIX - self.MONOLITHIC = MONOLITHIC - self.STABILIZATION_TYPE = STABILIZATION_TYPE - self.ENTROPY_TYPE = ENTROPY_TYPE - self.FCT = FCT - self.num_fct_iter=num_fct_iter - self.uL = uL - self.uR = uR - self.cK = cK - self.forceStrongConditions = True - self.cE = cE - self.outputQuantDOFs = outputQuantDOFs - TC_base.__init__(self, - nc, - mass, - advection, - diffusion, - potential, - reaction, - hamiltonian, - variableNames, - sparseDiffusionTensors = sparseDiffusionTensors, - useSparseDiffusion = True) - - def initializeMesh(self,mesh): - from proteus.SubsurfaceTransportCoefficients import BlockHeterogeneousCoefficients - self.elementMaterialTypes,self.exteriorElementBoundaryTypes,self.elementBoundaryTypes = BlockHeterogeneousCoefficients(mesh).initializeMaterialTypes() - #want element boundary material types for evaluating heterogeneity - #not boundary conditions - self.isSeepageFace = np.zeros((mesh.nExteriorElementBoundaries_global),'i') - if self.getSeepageFace != None: - for ebNE in range(mesh.nExteriorElementBoundaries_global): - #mwf missing ebNE-->ebN? - ebN = mesh.exteriorElementBoundariesArray[ebNE] - #print "eb flag",mesh.elementBoundaryMaterialTypes[ebN] - #print("Hi, Arnob") - #print self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) - self.isSeepageFace[ebNE] = self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) - #print (self.isSeepageFace) - def initializeElementQuadrature(self,t,cq): - self.materialTypes_q = self.elementMaterialTypes - self.q_shape = cq[('u',0)].shape - #self.anb_seepage_flux= anb_seepage_flux - #print("The seepage is ", anb_seepage_flux) -# cq['Ks'] = np.zeros(self.q_shape,'d') -# for k in range(self.q_shape[1]): -# cq['Ks'][:,k] = self.Ksw_types[self.elementMaterialTypes,0] - self.q[('vol_frac',0)] = np.zeros(self.q_shape,'d') - def initializeElementBoundaryQuadrature(self,t,cebq,cebq_global): - self.materialTypes_ebq = np.zeros(cebq[('u',0)].shape[0:2],'i') - self.ebq_shape = cebq[('u',0)].shape - for ebN_local in range(self.ebq_shape[1]): - self.materialTypes_ebq[:,ebN_local] = self.elementMaterialTypes - self.ebq[('vol_frac',0)] = np.zeros(self.ebq_shape,'d') - - def initializeGlobalExteriorElementBoundaryQuadrature(self,t,cebqe): - self.materialTypes_ebqe = self.exteriorElementBoundaryTypes - self.ebqe_shape = cebqe[('u',0)].shape - self.ebqe[('vol_frac',0)] = np.zeros(self.ebqe_shape,'d') - # - - - def evaluate(self,t,c): - if c[('u',0)].shape == self.q_shape: - materialTypes = self.materialTypes_q - vol_frac = self.q[('vol_frac',0)] - elif c[('u',0)].shape == self.ebqe_shape: - materialTypes = self.materialTypes_ebqe - vol_frac = self.ebqe[('vol_frac',0)] - elif c[('u',0)].shape == self.ebq_shape: - materialTypes = self.materialTypes_ebq - vol_frac = self.ebq[('vol_frac',0)] - else: - assert False, "no materialType found to match c[('u',0)].shape= %s " % c[('u',0)].shape - self.conservativeHeadRichardsMualemVanGenuchten_sd_het(self.sdInfo[(0,0)][0], - self.sdInfo[(0,0)][1], - materialTypes, - self.rho, - self.beta, - self.gravity, - self.vgm_alpha_types, - self.vgm_n_types, - self.thetaR_types, - self.thetaSR_types, - self.Ksw_types, - c[('u',0)], - c[('m',0)], - c[('dm',0,0)], - c[('f',0)], - c[('df',0,0)], - c[('a',0,0)], - c[('da',0,0,0)], - vol_frac) - # print "Picard---------------------------------------------------------------" - # c[('df',0,0)][:] = 0.0 - # c[('da',0,0,0)][:] = 0.0 -# self.conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2(materialTypes, -# self.rho, -# self.beta, -# self.gravity, -# self.vgm_alpha_types, -# self.vgm_n_types, -# self.thetaR_types, -# self.thetaSR_types, -# self.Ksw_types, -# c[('u',0)], -# c[('m',0)], -# c[('dm',0,0)], -# c[('f',0)], -# c[('df',0,0)], -# c[('a',0,0)], -# c[('da',0,0,0)]) - #mwf debug - if (np.isnan(c[('da',0,0,0)]).any() or - np.isnan(c[('a',0,0)]).any() or - np.isnan(c[('df',0,0)]).any() or - np.isnan(c[('f',0)]).any() or - np.isnan(c[('u',0)]).any() or - np.isnan(c[('m',0)]).any() or - np.isnan(c[('dm',0,0)]).any()): - import pdb - pdb.set_trace() - - def postStep(self, t, firstStep=False): - # #anb_seepage_flux_n[:]= self.anb_seepage_flux - with open('seepage_stab_0', "a") as f: - # f.write("\n Time"+ ",\t" +"Seepage\n") - f.write(repr(t)+ ",\t")# +repr(np.sum(self.LevelModel.anb_seepage_flux_n))) - -class LevelModel(proteus.Transport.OneLevelTransport): - nCalls=0 - def __init__(self, - uDict, - phiDict, - testSpaceDict, - matType, - dofBoundaryConditionsDict, - dofBoundaryConditionsSetterDict, - coefficients, - elementQuadrature, - elementBoundaryQuadrature, - fluxBoundaryConditionsDict=None, - advectiveFluxBoundaryConditionsSetterDict=None, - diffusiveFluxBoundaryConditionsSetterDictDict=None, - stressTraceBoundaryConditionsSetterDict=None, - stabilization=None, - shockCapturing=None, - conservativeFluxDict=None, - numericalFluxType=None, - TimeIntegrationClass=None, - massLumping=False, - reactionLumping=False, - options=None, - name='defaultName', - reuse_trial_and_test_quadrature=True, - sd = True, - movingDomain=False, - bdyNullSpace=False): - self.bdyNullSpace=bdyNullSpace - # - #set the objects describing the method and boundary conditions - # - self.movingDomain=movingDomain - self.tLast_mesh=None - # - self.name=name - self.sd=sd - self.Hess=False - self.lowmem=True - self.timeTerm=True#allow turning off the time derivative - #self.lowmem=False - self.testIsTrial=True - self.phiTrialIsTrial=True - self.u = uDict - self.ua = {}#analytical solutions - self.phi = phiDict - self.dphi={} - self.matType = matType - #mwf try to reuse test and trial information across components if spaces are the same - self.reuse_test_trial_quadrature = reuse_trial_and_test_quadrature#True#False - if self.reuse_test_trial_quadrature: - for ci in range(1,coefficients.nc): - assert self.u[ci].femSpace.__class__.__name__ == self.u[0].femSpace.__class__.__name__, "to reuse_test_trial_quad all femSpaces must be the same!" - self.u_dof_old = None - ## Simplicial Mesh - self.mesh = self.u[0].femSpace.mesh #assume the same mesh for all components for now - self.testSpace = testSpaceDict - self.dirichletConditions = dofBoundaryConditionsDict - self.dirichletNodeSetList=None #explicit Dirichlet conditions for now, no Dirichlet BC constraints - self.coefficients = coefficients - self.coefficients.initializeMesh(self.mesh) - self.nc = self.coefficients.nc - self.stabilization = stabilization - self.shockCapturing = shockCapturing - self.conservativeFlux = conservativeFluxDict #no velocity post-processing for now - self.fluxBoundaryConditions=fluxBoundaryConditionsDict - self.advectiveFluxBoundaryConditionsSetterDict=advectiveFluxBoundaryConditionsSetterDict - self.diffusiveFluxBoundaryConditionsSetterDictDict = diffusiveFluxBoundaryConditionsSetterDictDict - #determine whether the stabilization term is nonlinear - self.stabilizationIsNonlinear = False - #cek come back - if self.stabilization != None: - for ci in range(self.nc): - if ci in coefficients.mass: - for flag in list(coefficients.mass[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.advection: - for flag in list(coefficients.advection[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.diffusion: - for diffusionDict in list(coefficients.diffusion[ci].values()): - for flag in list(diffusionDict.values()): - if flag != 'constant': - self.stabilizationIsNonlinear=True - if ci in coefficients.potential: - for flag in list(coefficients.potential[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.reaction: - for flag in list(coefficients.reaction[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.hamiltonian: - for flag in list(coefficients.hamiltonian[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - #determine if we need element boundary storage - self.elementBoundaryIntegrals = {} - for ci in range(self.nc): - self.elementBoundaryIntegrals[ci] = ((self.conservativeFlux != None) or - (numericalFluxType != None) or - (self.fluxBoundaryConditions[ci] == 'outFlow') or - (self.fluxBoundaryConditions[ci] == 'mixedFlow') or - (self.fluxBoundaryConditions[ci] == 'setFlow')) - # - #calculate some dimensions - # - self.nSpace_global = self.u[0].femSpace.nSpace_global #assume same space dim for all variables - self.nDOF_trial_element = [u_j.femSpace.max_nDOF_element for u_j in list(self.u.values())] - self.nDOF_phi_trial_element = [phi_k.femSpace.max_nDOF_element for phi_k in list(self.phi.values())] - self.n_phi_ip_element = [phi_k.femSpace.referenceFiniteElement.interpolationConditions.nQuadraturePoints for phi_k in list(self.phi.values())] - self.nDOF_test_element = [femSpace.max_nDOF_element for femSpace in list(self.testSpace.values())] - self.nFreeDOF_global = [dc.nFreeDOF_global for dc in list(self.dirichletConditions.values())] - self.nVDOF_element = sum(self.nDOF_trial_element) - self.nFreeVDOF_global = sum(self.nFreeDOF_global) - # - NonlinearEquation.__init__(self,self.nFreeVDOF_global) - # - #build the quadrature point dictionaries from the input (this - #is just for convenience so that the input doesn't have to be - #complete) - # - elementQuadratureDict={} - elemQuadIsDict = isinstance(elementQuadrature,dict) - if elemQuadIsDict: #set terms manually - for I in self.coefficients.elementIntegralKeys: - if I in elementQuadrature: - elementQuadratureDict[I] = elementQuadrature[I] - - else: - elementQuadratureDict[I] = elementQuadrature['default'] - else: - for I in self.coefficients.elementIntegralKeys: - elementQuadratureDict[I] = elementQuadrature - if self.stabilization != None: - for I in self.coefficients.elementIntegralKeys: - if elemQuadIsDict: - if I in elementQuadrature: - elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature[I] - else: - elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature['default'] - else: - elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature - if self.shockCapturing != None: - for ci in self.shockCapturing.components: - if elemQuadIsDict: - if ('numDiff',ci,ci) in elementQuadrature: - elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature[('numDiff',ci,ci)] - #print("Hi, Arnob1") - #print(anb_seepage_flux) - else: - elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature['default'] - #print("Hi, Arnob2") - #print(anb_seepage_flux) - else: - elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature - print("Hi, Arnob3") - #print(anb_seepage_flux) - if massLumping: - for ci in list(self.coefficients.mass.keys()): - elementQuadratureDict[('m',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - print("Hi, Arnob4") - #print(anb_seepage_flux) - for I in self.coefficients.elementIntegralKeys: - elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - print("Hi, Arnob5") - #print(anb_seepage_flux) - if reactionLumping: - for ci in list(self.coefficients.mass.keys()): - elementQuadratureDict[('r',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - print("Hi, Arnob6") - #print(anb_seepage_flux) - for I in self.coefficients.elementIntegralKeys: - elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - print("Hi, Arnob7") - #print(anb_seepage_flux) - elementBoundaryQuadratureDict={} - if isinstance(elementBoundaryQuadrature,dict): #set terms manually - for I in self.coefficients.elementBoundaryIntegralKeys: - if I in elementBoundaryQuadrature: - elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature[I] - print("Hi, Arnob8") - #print(anb_seepage_flux) - else: - elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature['default'] - #print("Hi, Arnob9") - #print(anb_seepage_flux) - else: - for I in self.coefficients.elementBoundaryIntegralKeys: - elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature - print("Hi, Arnob10") - #print(anb_seepage_flux) - # - # find the union of all element quadrature points and - # build a quadrature rule for each integral that has a - # weight at each point in the union - #mwf include tag telling me which indices are which quadrature rule? - (self.elementQuadraturePoints,self.elementQuadratureWeights, - self.elementQuadratureRuleIndeces) = Quadrature.buildUnion(elementQuadratureDict) - self.nQuadraturePoints_element = self.elementQuadraturePoints.shape[0] - self.nQuadraturePoints_global = self.nQuadraturePoints_element*self.mesh.nElements_global - # - #Repeat the same thing for the element boundary quadrature - # - (self.elementBoundaryQuadraturePoints, - self.elementBoundaryQuadratureWeights, - self.elementBoundaryQuadratureRuleIndeces) = Quadrature.buildUnion(elementBoundaryQuadratureDict) - self.nElementBoundaryQuadraturePoints_elementBoundary = self.elementBoundaryQuadraturePoints.shape[0] - self.nElementBoundaryQuadraturePoints_global = (self.mesh.nElements_global* - self.mesh.nElementBoundaries_element* - self.nElementBoundaryQuadraturePoints_elementBoundary) -# if isinstance(self.u[0].femSpace,C0_AffineLinearOnSimplexWithNodalBasis): -# print self.nQuadraturePoints_element -# if self.nSpace_global == 3: -# assert(self.nQuadraturePoints_element == 5) -# elif self.nSpace_global == 2: -# assert(self.nQuadraturePoints_element == 6) -# elif self.nSpace_global == 1: -# assert(self.nQuadraturePoints_element == 3) -# -# print self.nElementBoundaryQuadraturePoints_elementBoundary -# if self.nSpace_global == 3: -# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) -# elif self.nSpace_global == 2: -# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) -# elif self.nSpace_global == 1: -# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 1) - - # - #storage dictionaries - self.scalars_element = set() - # - #simplified allocations for test==trial and also check if space is mixed or not - # - self.q={} - self.ebq={} - self.ebq_global={} - self.ebqe={} - self.phi_ip={} - self.edge_based_cfl = np.zeros(self.u[0].dof.shape)+100 - #mesh - #self.q['x'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,3),'d') - self.q[('dV_u', 0)] = (old_div(1.0, self.mesh.nElements_global)) * np.ones((self.mesh.nElements_global, self.nQuadraturePoints_element), 'd') - self.ebqe['x'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,3),'d') - self.q[('u',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') - self.q[('grad(u)',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') - self.q['velocity'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') - self.q[('m',0)] = self.q[('u',0)].copy() - self.q[('mt',0)] = self.q[('u',0)].copy() - self.q[('m_last',0)] = self.q[('u',0)].copy() - self.q[('m_tmp',0)] = self.q[('u',0)].copy() - self.q[('cfl',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') - self.q[('numDiff',0,0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') - self.ebqe[('u',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.ebqe[('grad(u)',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') - self.ebqe['velocity'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') - self.ebqe[('advectiveFlux_bc_flag',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'i') - self.ebqe[('advectiveFlux_bc',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.ebqe[('advectiveFlux',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.ebqe[('penalty')] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.points_elementBoundaryQuadrature= set() - self.scalars_elementBoundaryQuadrature= set([('u',ci) for ci in range(self.nc)]) - self.vectors_elementBoundaryQuadrature= set() - self.tensors_elementBoundaryQuadrature= set() - self.inflowBoundaryBC = {} - self.inflowBoundaryBC_values = {} - self.inflowFlux = {} - for cj in range(self.nc): - self.inflowBoundaryBC[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,),'i') - self.inflowBoundaryBC_values[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nDOF_trial_element[cj]),'d') - self.inflowFlux[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.internalNodes = set(range(self.mesh.nNodes_global)) - #identify the internal nodes this is ought to be in mesh - ##\todo move this to mesh - for ebNE in range(self.mesh.nExteriorElementBoundaries_global): - ebN = self.mesh.exteriorElementBoundariesArray[ebNE] - eN_global = self.mesh.elementBoundaryElementsArray[ebN,0] - ebN_element = self.mesh.elementBoundaryLocalElementBoundariesArray[ebN,0] - for i in range(self.mesh.nNodes_element): - if i != ebN_element: - I = self.mesh.elementNodesArray[eN_global,i] - self.internalNodes -= set([I]) - self.nNodes_internal = len(self.internalNodes) - self.internalNodesArray=np.zeros((self.nNodes_internal,),'i') - for nI,n in enumerate(self.internalNodes): - self.internalNodesArray[nI]=n - # - del self.internalNodes - self.internalNodes = None - logEvent("Updating local to global mappings",2) - self.updateLocal2Global() - logEvent("Building time integration object",2) - logEvent(memory("inflowBC, internalNodes,updateLocal2Global","OneLevelTransport"),level=4) - #mwf for interpolating subgrid error for gradients etc - if self.stabilization and self.stabilization.usesGradientStabilization: - self.timeIntegration = TimeIntegrationClass(self,integrateInterpolationPoints=True) - else: - self.timeIntegration = TimeIntegrationClass(self) - - if options != None: - self.timeIntegration.setFromOptions(options) - logEvent(memory("TimeIntegration","OneLevelTransport"),level=4) - logEvent("Calculating numerical quadrature formulas",2) - self.calculateQuadrature() - #lay out components/equations contiguously for now - self.offset = [0] - for ci in range(1,self.nc): - self.offset += [self.offset[ci-1]+self.nFreeDOF_global[ci-1]] - self.stride = [1 for ci in range(self.nc)] - #use contiguous layout of components for parallel, requires weak DBC's - # mql. Some ASSERTS to restrict the combination of the methods - if self.coefficients.STABILIZATION_TYPE > 0: - pass - #assert self.timeIntegration.isSSP == True, "If STABILIZATION_TYPE>0, use RKEV timeIntegration within VOF model" - #cond = 'levelNonlinearSolver' in dir(options) and (options.levelNonlinearSolver == - # ExplicitLumpedMassMatrixForRichards or options.levelNonlinearSolver == ExplicitConsistentMassMatrixForRichards) - #assert cond, "If STABILIZATION_TYPE>0, use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards or ExplicitConsistentMassMatrixForRichards" - try: - if 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards: - assert self.coefficients.LUMPED_MASS_MATRIX, "If levelNonlinearSolver=ExplicitLumpedMassMatrix, use LUMPED_MASS_MATRIX=True" - except: - pass - if self.coefficients.LUMPED_MASS_MATRIX == True: - cond = self.coefficients.STABILIZATION_TYPE == 2 - assert cond, "Use lumped mass matrix just with: STABILIZATION_TYPE=2 (smoothness based stab.)" - cond = 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards - assert cond, "Use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards when the mass matrix is lumped" - - ################################################################# - ####################ARNOB_FCT_EDIT############################### - ################################################################# - - if self.coefficients.LUMPED_MASS_MATRIX == False: - cond = self.coefficients.STABILIZATION_TYPE == 2 - assert cond, "Use lumped mass matrix just with: STABILIZATION_TYPE=2 (smoothness based stab.)" - cond = 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == Newton - #assert cond, "Use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards when the mass matrix is lumped" - - - - - - if self.coefficients.FCT == True: - cond = self.coefficients.STABILIZATION_TYPE > 0, "Use FCT just with STABILIZATION_TYPE>0; i.e., edge based stabilization" - # END OF ASSERTS - - # cek adding empty data member for low order numerical viscosity structures here for now - self.ML = None # lumped mass matrix - self.MC_global = None # consistent mass matrix - self.cterm_global = None - self.cterm_transpose_global = None - # dL_global and dC_global are not the full matrices but just the CSR arrays containing the non zero entries - self.residualComputed=False #TMP - self.dLow= None - self.fluxMatrix = None - self.uDotLow = None - self.uLow = None - self.dt_times_dC_minus_dL = None - self.min_s_bc = None - self.max_s_bc = None - # Aux quantity at DOFs to be filled by optimized code (MQL) - self.quantDOFs = np.zeros(self.u[0].dof.shape, 'd') - self.sLow = np.zeros(self.u[0].dof.shape, 'd') - self.sHigh = np.zeros(self.u[0].dof.shape, 'd') - self.sn = np.zeros(self.u[0].dof.shape, 'd') - self.anb_seepage_flux_n = np.zeros(self.u[0].dof.shape, 'd') - comm = Comm.get() - self.comm=comm - if comm.size() > 1: - assert numericalFluxType != None and numericalFluxType.useWeakDirichletConditions,"You must use a numerical flux to apply weak boundary conditions for parallel runs" - self.offset = [0] - for ci in range(1,self.nc): - self.offset += [ci] - self.stride = [self.nc for ci in range(self.nc)] - # - logEvent(memory("stride+offset","OneLevelTransport"),level=4) - - - if numericalFluxType != None: - if options is None or options.periodicDirichletConditions is None: - self.numericalFlux = numericalFluxType(self, - dofBoundaryConditionsSetterDict, - advectiveFluxBoundaryConditionsSetterDict, - diffusiveFluxBoundaryConditionsSetterDictDict) - else: - self.numericalFlux = numericalFluxType(self, - dofBoundaryConditionsSetterDict, - advectiveFluxBoundaryConditionsSetterDict, - diffusiveFluxBoundaryConditionsSetterDictDict, - options.periodicDirichletConditions) - else: - self.numericalFlux = None - #set penalty terms - #cek todo move into numerical flux initialization - if 'penalty' in self.ebq_global: - for ebN in range(self.mesh.nElementBoundaries_global): - for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): - self.ebq_global['penalty'][ebN,k] = old_div(self.numericalFlux.penalty_constant,(self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power)) - #penalty term - #cek move to Numerical flux initialization - if 'penalty' in self.ebqe: - for ebNE in range(self.mesh.nExteriorElementBoundaries_global): - ebN = self.mesh.exteriorElementBoundariesArray[ebNE] - for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): - self.ebqe['penalty'][ebNE,k] = old_div(self.numericalFlux.penalty_constant,self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power) - logEvent(memory("numericalFlux","OneLevelTransport"),level=4) - self.elementEffectiveDiametersArray = self.mesh.elementInnerDiametersArray - #use post processing tools to get conservative fluxes, None by default - from proteus import PostProcessingTools - self.velocityPostProcessor = PostProcessingTools.VelocityPostProcessingChooser(self) - logEvent(memory("velocity postprocessor","OneLevelTransport"),level=4) - #helper for writing out data storage - from proteus import Archiver - self.elementQuadratureDictionaryWriter = Archiver.XdmfWriter() - self.elementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() - self.exteriorElementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() - #TODO get rid of this - for ci,fbcObject in list(self.fluxBoundaryConditionsObjectsDict.items()): - self.ebqe[('advectiveFlux_bc_flag',ci)] = np.zeros(self.ebqe[('advectiveFlux_bc',ci)].shape,'i') - for t,g in list(fbcObject.advectiveFluxBoundaryConditionsDict.items()): - if ci in self.coefficients.advection: - self.ebqe[('advectiveFlux_bc',ci)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) - self.ebqe[('advectiveFlux_bc_flag',ci)][t[0],t[1]] = 1 - - if hasattr(self.numericalFlux,'setDirichletValues'): - self.numericalFlux.setDirichletValues(self.ebqe) - if not hasattr(self.numericalFlux,'isDOFBoundary'): - self.numericalFlux.isDOFBoundary = {0:np.zeros(self.ebqe[('u',0)].shape,'i')} - if not hasattr(self.numericalFlux,'ebqe'): - self.numericalFlux.ebqe = {('u',0):np.zeros(self.ebqe[('u',0)].shape,'d')} - #TODO how to handle redistancing calls for calculateCoefficients,calculateElementResidual etc - self.globalResidualDummy = None - compKernelFlag=0 - self.delta_x_ij=None - self.richards = cRichards_base(self.nSpace_global, - self.nQuadraturePoints_element, - self.u[0].femSpace.elementMaps.localFunctionSpace.dim, - self.u[0].femSpace.referenceFiniteElement.localFunctionSpace.dim, - self.testSpace[0].referenceFiniteElement.localFunctionSpace.dim, - self.nElementBoundaryQuadraturePoints_elementBoundary, - compKernelFlag) - if self.movingDomain: - self.MOVING_DOMAIN=1.0 - else: - self.MOVING_DOMAIN=0.0 - #cek hack - self.movingDomain=False - self.MOVING_DOMAIN=0.0 - if self.mesh.nodeVelocityArray is None: - self.mesh.nodeVelocityArray = np.zeros(self.mesh.nodeArray.shape,'d') - self.forceStrongConditions=True - self.dirichletConditionsForceDOF = {} - if self.forceStrongConditions: - for cj in range(self.nc): - self.dirichletConditionsForceDOF[cj] = DOFBoundaryConditions(self.u[cj].femSpace,dofBoundaryConditionsSetterDict[cj],weakDirichletConditions=False) - def FCTStep(self): - import pdb - rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() - limited_solution = np.zeros((len(rowptr) - 1),'d') - #self.u_free_dof_stage_0_l = np.zeros((len(rowptr) - 1),'d') - #self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage], # soln - #fromFreeToGlobal=0 - #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - # self.offset[0], - # self.stride[0], - # self.dirichletConditions[0].global2freeGlobal_global_dofs, - # self.dirichletConditions[0].global2freeGlobal_free_dofs, - # self.u_free_dof_stage_0_l, - # self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage]) - argsDict = cArgumentsDict.ArgumentsDict() - argsDict["bc_mask"] = self.bc_mask - argsDict["NNZ"] = self.nnz - argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs - argsDict["dt"] = self.timeIntegration.dt - argsDict["lumped_mass_matrix"] = self.ML - argsDict["soln"] = self.sn - argsDict["pn"] = self.u[0].dof - argsDict["solH"] = self.sHigh - argsDict["uLow"] = self.sLow - argsDict["uDotLow"] = self.uDotLow - argsDict["limited_solution"] = limited_solution - argsDict["csrRowIndeces_DofLoops"] = rowptr - argsDict["csrColumnOffsets_DofLoops"] = colind - argsDict["MassMatrix"] = MassMatrix - argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL - argsDict["min_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0]) #cek hack just set from physical bounds - argsDict["max_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0] + self.coefficients.thetaSR_types[0]) #cek hack - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - argsDict["MONOLITHIC"] =0#cek hack self.coefficients.MONOLITHIC - argsDict["anb_seepage_flux_n"]= self.anb_seepage_flux_n - #pdb.set_trace() - self.richards.FCTStep(argsDict) - - # self.nnz, # number of non zero entries - # len(rowptr) - 1, # number of DOFs - # self.timeIntegration.dt, - # self.ML, # Lumped mass matrix - # self.sn, - # self.u_dof_old, - # self.sHigh, # high order solution - # self.sLow, - # limited_solution, - # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) - # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) - # MassMatrix, - # self.dt_times_dC_minus_dL, - # self.min_s_bc, - # self.max_s_bc, - # self.coefficients.LUMPED_MASS_MATRIX, - # self.coefficients.MONOLITHIC) - old_dof = self.u[0].dof.copy() - self.invert(limited_solution, self.u[0].dof) - self.timeIntegration.u[:] = self.u[0].dof - #fromFreeToGlobal=1 #direction copying - #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - # self.offset[0], - # self.stride[0], - # self.dirichletConditions[0].global2freeGlobal_global_dofs, - # self.dirichletConditions[0].global2freeGlobal_free_dofs, - # self.u[0].dof, - # limited_solution) - def kth_FCT_step(self): - #import pdb - #pdb.set_trace() - rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() - limitedFlux = np.zeros(self.nnz) - limited_solution = np.zeros((len(rowptr) - 1),'d') - #limited_solution[:] = self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage] - fromFreeToGlobal=0 #direction copying - cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - self.offset[0], - self.stride[0], - self.dirichletConditions[0].global2freeGlobal_global_dofs, - self.dirichletConditions[0].global2freeGlobal_free_dofs, - limited_solution, - self.timeintegration.u_dof_stage[0][self.timeIntegration.lstage]) - - self.richards.kth_FCT_step( - self.timeIntegration.dt, - self.coefficients.num_fct_iter, - self.nnz, # number of non zero entries - len(rowptr) - 1, # number of DOFs - MassMatrix, - self.ML, # Lumped mass matrix - self.u_dof_old, - limited_solution, - self.uDotLow, - self.uLow, - self.dLow, - self.fluxMatrix, - limitedFlux, - rowptr, - colind) - - self.timeIntegration.u[:] = limited_solution - #self.u[0].dof[:] = limited_solution - fromFreeToGlobal=1 #direction copying - cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - self.offset[0], - self.stride[0], - self.dirichletConditions[0].global2freeGlobal_global_dofs, - self.dirichletConditions[0].global2freeGlobal_free_dofs, - self.u[0].dof, - limited_solution) - def calculateCoefficients(self): - pass - def calculateElementResidual(self): - if self.globalResidualDummy != None: - self.getResidual(self.u[0].dof,self.globalResidualDummy) - def getResidual(self,u,r): - import pdb - import copy - """ - Calculate the element residuals and add in to the global residual - """ - cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, - self.jacobian) - if self.u_dof_old is None: - # Pass initial condition to u_dof_old - self.u_dof_old = np.copy(self.u[0].dof) - rowptr, colind, nzval = self.jacobian.getCSRrepresentation() - nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix - r.fill(0.0) - ######################## - ### COMPUTE C MATRIX ### - ######################## - if self.cterm_global is None: - # since we only need cterm_global to persist, we can drop the other self.'s - self.cterm = {} - self.cterm_a = {} - self.cterm_global = {} - self.cterm_transpose = {} - self.cterm_a_transpose = {} - self.cterm_global_transpose = {} - rowptr, colind, nzval = self.jacobian.getCSRrepresentation() - nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix - di = self.q[('grad(u)', 0)].copy() # direction of derivative - # JACOBIANS (FOR ELEMENT TRANSFORMATION) - self.q[('J')] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nSpace_global, - self.nSpace_global), - 'd') - self.q[('inverse(J)')] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nSpace_global, - self.nSpace_global), - 'd') - self.q[('det(J)')] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element), - 'd') - self.u[0].femSpace.elementMaps.getJacobianValues(self.elementQuadraturePoints, - self.q['J'], - self.q['inverse(J)'], - self.q['det(J)']) - self.q['abs(det(J))'] = np.abs(self.q['det(J)']) - # SHAPE FUNCTIONS - self.q[('w', 0)] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nDOF_test_element[0]), - 'd') - self.q[('w*dV_m', 0)] = self.q[('w', 0)].copy() - self.u[0].femSpace.getBasisValues(self.elementQuadraturePoints, self.q[('w', 0)]) - cfemIntegrals.calculateWeightedShape(self.elementQuadratureWeights[('u', 0)], - self.q['abs(det(J))'], - self.q[('w', 0)], - self.q[('w*dV_m', 0)]) - # GRADIENT OF TEST FUNCTIONS - self.q[('grad(w)', 0)] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nDOF_test_element[0], - self.nSpace_global), - 'd') - self.u[0].femSpace.getBasisGradientValues(self.elementQuadraturePoints, - self.q['inverse(J)'], - self.q[('grad(w)', 0)]) - self.q[('grad(w)*dV_f', 0)] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nDOF_test_element[0], - self.nSpace_global), - 'd') - cfemIntegrals.calculateWeightedShapeGradients(self.elementQuadratureWeights[('u', 0)], - self.q['abs(det(J))'], - self.q[('grad(w)', 0)], - self.q[('grad(w)*dV_f', 0)]) - ########################## - ### LUMPED MASS MATRIX ### - ########################## - # assume a linear mass term - dm = np.ones(self.q[('u', 0)].shape, 'd') - elementMassMatrix = np.zeros((self.mesh.nElements_global, - self.nDOF_test_element[0], - self.nDOF_trial_element[0]), 'd') - cfemIntegrals.updateMassJacobian_weak_lowmem(dm, - self.q[('w', 0)], - self.q[('w*dV_m', 0)], - elementMassMatrix) - self.MC_a = nzval.copy() - self.MC_global = SparseMat(self.nFreeDOF_global[0], - self.nFreeDOF_global[0], - nnz, - self.MC_a, - colind, - rowptr) - cfemIntegrals.zeroJacobian_CSR(self.nnz, self.MC_global) - cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.csrRowIndeces[(0, 0)], - self.csrColumnOffsets[(0, 0)], - elementMassMatrix, - self.MC_global) - self.ML = np.zeros((self.nFreeDOF_global[0],), 'd') - for i in range(self.nFreeDOF_global[0]): - self.ML[i] = self.MC_a[rowptr[i]:rowptr[i + 1]].sum() - np.testing.assert_almost_equal(self.ML.sum(), - self.mesh.volume, - err_msg="Trace of lumped mass matrix should be the domain volume", verbose=True) - for d in range(self.nSpace_global): # spatial dimensions - # C matrices - self.cterm[d] = np.zeros((self.mesh.nElements_global, - self.nDOF_test_element[0], - self.nDOF_trial_element[0]), 'd') - self.cterm_a[d] = nzval.copy() - #self.cterm_a[d] = np.zeros(nzval.size) - self.cterm_global[d] = SparseMat(self.nFreeDOF_global[0], - self.nFreeDOF_global[0], - nnz, - self.cterm_a[d], - colind, - rowptr) - cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global[d]) - di[:] = 0.0 - di[..., d] = 1.0 - cfemIntegrals.updateHamiltonianJacobian_weak_lowmem(di, - self.q[('grad(w)*dV_f', 0)], - self.q[('w', 0)], - self.cterm[d]) # int[(di*grad(wj))*wi*dV] - cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.csrRowIndeces[(0, 0)], - self.csrColumnOffsets[(0, 0)], - self.cterm[d], - self.cterm_global[d]) - # C Transpose matrices - self.cterm_transpose[d] = np.zeros((self.mesh.nElements_global, - self.nDOF_test_element[0], - self.nDOF_trial_element[0]), 'd') - self.cterm_a_transpose[d] = nzval.copy() - self.cterm_global_transpose[d] = SparseMat(self.nFreeDOF_global[0], - self.nFreeDOF_global[0], - nnz, - self.cterm_a_transpose[d], - colind, - rowptr) - cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global_transpose[d]) - di[:] = 0.0 - di[..., d] = -1.0 - cfemIntegrals.updateAdvectionJacobian_weak_lowmem(di, - self.q[('w', 0)], - self.q[('grad(w)*dV_f', 0)], - self.cterm_transpose[d]) # -int[(-di*grad(wi))*wj*dV] - cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.csrRowIndeces[(0, 0)], - self.csrColumnOffsets[(0, 0)], - self.cterm_transpose[d], - self.cterm_global_transpose[d]) - - rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() - else: - Cy = np.zeros(Cx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() - else: - Cz = np.zeros(Cx.shape, 'd') - rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() - else: - CTy = np.zeros(CTx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() - else: - CTz = np.zeros(CTx.shape, 'd') - - # This is dummy. I just care about the csr structure of the sparse matrix - self.dLow = np.zeros(Cx.shape, 'd') - self.fluxMatrix = np.zeros(Cx.shape, 'd') - self.dt_times_dC_minus_dL = np.zeros(Cx.shape, 'd') - nFree = len(rowptr)-1 - self.min_s_bc = np.zeros(nFree, 'd') + 1E10 - self.max_s_bc = np.zeros(nFree, 'd') - 1E10 - self.uDotLow = np.zeros(nFree, 'd') - self.uLow = np.zeros(nFree, 'd') - # - # cek end computationa of cterm_global - # - # cek showing mquezada an example of using cterm_global sparse matrix - # calculation y = c*x where x==1 - # direction=0 - #rowptr, colind, c = self.cterm_global[direction].getCSRrepresentation() - #y = np.zeros((self.nFreeDOF_global[0],),'d') - #x = np.ones((self.nFreeDOF_global[0],),'d') - # ij=0 - # for i in range(self.nFreeDOF_global[0]): - # for offset in range(rowptr[i],rowptr[i+1]): - # j = colind[offset] - # y[i] += c[ij]*x[j] - # ij+=1 - #Load the unknowns into the finite element dof - self.timeIntegration.calculateCoefs() - self.timeIntegration.calculateU(u) - self.setUnknowns(self.timeIntegration.u) - #cek can put in logic to skip of BC's don't depend on t or u - #Dirichlet boundary conditions - self.numericalFlux.setDirichletValues(self.ebqe) - #flux boundary conditions - #cek hack, just using advective flux for flux BC for now - for t,g in list(self.fluxBoundaryConditionsObjectsDict[0].advectiveFluxBoundaryConditionsDict.items()): - self.ebqe[('advectiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) - self.ebqe[('advectiveFlux_bc_flag',0)][t[0],t[1]] = 1 - # for t,g in self.fluxBoundaryConditionsObjectsDict[0].diffusiveFluxBoundaryConditionsDict.iteritems(): - # self.ebqe[('diffusiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) - # self.ebqe[('diffusiveFlux_bc_flag',0)][t[0],t[1]] = 1 - #self.shockCapturing.lag=True - if self.forceStrongConditions: - self.bc_mask = np.ones_like(self.u[0].dof) - for cj in range(len(self.dirichletConditionsForceDOF)): - for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): - self.u[cj].dof[dofN] = g(self.dirichletConditionsForceDOF[cj].DOFBoundaryPointDict[dofN],self.timeIntegration.t) - self.u_dof_old[dofN] = self.u[cj].dof[dofN] - self.bc_mask[dofN] = 0.0 - degree_polynomial = 1 - try: - degree_polynomial = self.u[0].femSpace.order - except: - pass - - argsDict = cArgumentsDict.ArgumentsDict() - argsDict["bc_mask"] = self.bc_mask - argsDict["dt"] = self.timeIntegration.dt - argsDict["Theta"] = 1.0 - argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi - argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi - argsDict["mesh_dof"] = self.mesh.nodeArray - argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray - argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN - argsDict["mesh_l2g"] = self.mesh.elementNodesArray - argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] - argsDict["u_trial_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi - argsDict["u_test_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi - argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace - argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace - argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] - argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals - argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians - argsDict["nElements_global"] = self.mesh.nElements_global - argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] - argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, - argsDict["isSeepageFace"] = self.coefficients.isSeepageFace - argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] - argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] - argsDict["rho"] = self.coefficients.rho - argsDict["beta"] = self.coefficients.beta - argsDict["gravity"] = self.coefficients.gravity - argsDict["alpha"] = self.coefficients.vgm_alpha_types - argsDict["n"] = self.coefficients.vgm_n_types - argsDict["thetaR"] = self.coefficients.thetaR_types - argsDict["thetaSR"] = self.coefficients.thetaSR_types - argsDict["KWs"] = self.coefficients.Ksw_types - argsDict["useMetrics"] = 0.0 - argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf - argsDict["lag_shockCapturing"] = 0 - argsDict["shockCapturingDiffusion"] = 0.0 - argsDict["sc_uref"] = 0.0 - argsDict["sc_alpha"] = 0.0 - argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g - argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] - argsDict["elementDiameter"] = self.mesh.elementDiametersArray - argsDict["degree_polynomial"] = degree_polynomial - argsDict["u_dof"] = self.u[0].dof - argsDict["u_dof_old"] = self.u_dof_old - argsDict["velocity"] = self.q['velocity'] - argsDict["q_m"] = self.timeIntegration.m_tmp[0] - argsDict["q_u"] = self.q[('u',0)] - argsDict["q_dV"] = self.q[('dV_u',0)] - argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] - argsDict["cfl"] = self.q[('cfl',0)] - argsDict["q_numDiff_u"] = self.q[('cfl',0)] - argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] - argsDict["offset_u"] = self.offset[0] - argsDict["stride_u"] = self.stride[0] - argsDict["globalResidual"] = r - argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global - argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray - argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray - argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray - argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] - argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] - argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] - argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] - argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] - argsDict["ebqe_phi"] = self.ebqe[('u',0)] - argsDict["epsFact"] = 0.0 - argsDict["ebqe_u"] = self.ebqe[('u',0)] - argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] - argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE - # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION - argsDict["cE"] = self.coefficients.cE - argsDict["cK"] = self.coefficients.cK - # PARAMETERS FOR LOG BASED ENTROPY FUNCTION - argsDict["uL"] = self.coefficients.uL - argsDict["uR"] = self.coefficients.uR - # PARAMETERS FOR EDGE VISCOSITY - argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs - argsDict["NNZ"] = self.nnz - argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern - argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) - argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) - argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms - argsDict["globalJacobian"] = self.jacobian.getCSRrepresentation()[2] - # C matrices - argsDict["Cx"] = Cx - argsDict["Cy"] = Cy - argsDict["Cz"] = Cz - argsDict["CTx"] = CTx - argsDict["CTy"] = CTy - argsDict["CTz"] = CTz - argsDict["ML"] = self.ML - argsDict["delta_x_ij"] = self.delta_x_ij - # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE - argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE - # FLUX CORRECTED TRANSPORT - argsDict["dLow"] = self.dLow - argsDict["fluxMatrix"] = self.fluxMatrix - argsDict["uDotLow"] = self.uDotLow - argsDict["uLow"] = self.uLow - argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL - argsDict["min_s_bc"] = self.min_s_bc - argsDict["max_s_bc"] = self.max_s_bc - argsDict["quantDOFs"] = self.quantDOFs - argsDict["sLow"] = self.sLow - argsDict["sn"] = self.sn - argsDict["anb_seepage_flux_n"]= self.anb_seepage_flux_n -###################################################################################### - argsDict["pn"] = self.u[0].dof - argsDict["solH"] = self.sHigh - - rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() - argsDict["MassMatrix"] = MassMatrix - argsDict["solH"] = self.sHigh - -###################################################################################### - argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - #print(anb_seepage_flux) - #argsDict["anb_seepage_flux_n"] = self.coefficients.anb_seepage_flux_n - #if np.sum(anb_seepage_flux_n)>0: - - #logEvent("Hi, this is Arnob", self.anb_seepage_flux_n[0]) - print("Seepage Flux from Python file", np.sum(self.anb_seepage_flux_n)) - seepage_text_variable= np.sum(self.anb_seepage_flux_n) - - with open('seepage_stab_0',"a" ) as f: - #f.write("\n Time"+ ",\t" +"Seepage\n") - #f.write(repr(self.coefficients.t)+ ",\t" +repr(seepage_text_variable), "\n") - f.write(repr(seepage_text_variable)+ "\n") - if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG - self.calculateResidual = self.richards.calculateResidual - self.calculateJacobian = self.richards.calculateJacobian - else: - self.calculateResidual = self.richards.calculateResidual_entropy_viscosity - self.calculateJacobian = self.richards.calculateMassMatrix - if self.delta_x_ij is None: - self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') - self.calculateResidual(argsDict) - #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] - #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf - #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] - #self.timeIntegration.calculateElementCoefficients(self.q) - if self.forceStrongConditions:# - for cj in range(len(self.dirichletConditionsForceDOF)):# - for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): - r[self.offset[cj]+self.stride[cj]*dofN] = 0 - if self.stabilization: - self.stabilization.accumulateSubgridMassHistory(self.q) - logEvent("Global residual",level=9,data=r) - self.nonlinear_function_evaluations += 1 - if self.globalResidualDummy is None: - self.globalResidualDummy = np.zeros(r.shape,'d') - - #print("Hello from the python file", self.coefficients.anb_seepage_flux) - #logEvent("Hello from the python file", self.coefficients.anb_seepage_flux") - - - - - - def invert(self,u,r): - #u=s - #r=p - import pdb - import copy - """ - Calculate the element residuals and add in to the global residual - """ - self.sHigh[:] = u - rowptr, colind, nzval = self.jacobian.getCSRrepresentation() - nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix - r.fill(0.0) - rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() - else: - Cy = np.zeros(Cx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() - else: - Cz = np.zeros(Cx.shape, 'd') - rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() - else: - CTy = np.zeros(CTx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() - else: - CTz = np.zeros(CTx.shape, 'd') - - # This is dummy. I just care about the csr structure of the sparse matrix - nFree = len(rowptr)-1 - degree_polynomial = 1 - try: - degree_polynomial = self.u[0].femSpace.order - except: - pass - if self.delta_x_ij is None: - self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') - argsDict = cArgumentsDict.ArgumentsDict() - argsDict["dt"] = self.timeIntegration.dt - argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi - argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi - argsDict["mesh_dof"] = self.mesh.nodeArray - argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray - argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN - argsDict["mesh_l2g"] = self.mesh.elementNodesArray - argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] - argsDict["u_trial_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi - argsDict["u_test_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi - argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace - argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace - argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] - argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals - argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians - argsDict["nElements_global"] = self.mesh.nElements_global - argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] - argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, - argsDict["isSeepageFace"] = self.coefficients.isSeepageFace - argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] - argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] - argsDict["rho"] = self.coefficients.rho - argsDict["beta"] = self.coefficients.beta - argsDict["gravity"] = self.coefficients.gravity - argsDict["alpha"] = self.coefficients.vgm_alpha_types - argsDict["n"] = self.coefficients.vgm_n_types - argsDict["thetaR"] = self.coefficients.thetaR_types - argsDict["thetaSR"] = self.coefficients.thetaSR_types - argsDict["KWs"] = self.coefficients.Ksw_types - argsDict["useMetrics"] = 0.0 - argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf - argsDict["lag_shockCapturing"] = 0 - argsDict["shockCapturingDiffusion"] = 0.0 - argsDict["sc_uref"] = 0.0 - argsDict["sc_alpha"] = 0.0 - argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g - argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] - argsDict["elementDiameter"] = self.mesh.elementDiametersArray - argsDict["degree_polynomial"] = degree_polynomial - argsDict["u_dof"] = u#self.u[0].dof - argsDict["u_dof_old"] = self.u[0].dof - argsDict["velocity"] = self.q['velocity'] - argsDict["q_m"] = self.timeIntegration.m_tmp[0] - argsDict["q_u"] = self.q[('u',0)] - argsDict["q_dV"] = self.q[('dV_u',0)] - argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] - argsDict["cfl"] = self.q[('cfl',0)] - argsDict["q_numDiff_u"] = self.q[('cfl',0)] - argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] - argsDict["offset_u"] = self.offset[0] - argsDict["stride_u"] = self.stride[0] - argsDict["globalResidual"] = r - argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global - argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray - argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray - argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray - argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] - argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] - argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] - argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] - argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] - argsDict["ebqe_phi"] = self.ebqe[('u',0)] - argsDict["epsFact"] = 0.0 - argsDict["ebqe_u"] = self.ebqe[('u',0)] - argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] - argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE - # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION - argsDict["cE"] = self.coefficients.cE - argsDict["cK"] = self.coefficients.cK - # PARAMETERS FOR LOG BASED ENTROPY FUNCTION - argsDict["uL"] = self.coefficients.uL - argsDict["uR"] = self.coefficients.uR - # PARAMETERS FOR EDGE VISCOSITY - argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs - argsDict["NNZ"] = self.nnz - argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern - argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) - argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) - argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms - # C matrices - argsDict["Cx"] = Cx - argsDict["Cy"] = Cy - argsDict["Cz"] = Cz - argsDict["CTx"] = CTx - argsDict["CTy"] = CTy - argsDict["CTz"] = CTz - argsDict["ML"] = self.ML - argsDict["delta_x_ij"] = self.delta_x_ij - # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE - argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE - # FLUX CORRECTED TRANSPORT - argsDict["dLow"] = self.dLow - argsDict["fluxMatrix"] = self.fluxMatrix - argsDict["uDotLow"] = self.uDotLow - argsDict["uLow"] = self.uLow - argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL - argsDict["min_s_bc"] = self.min_s_bc - argsDict["max_s_bc"] = self.max_s_bc - argsDict["quantDOFs"] = self.quantDOFs - argsDict["sLow"] = self.sLow - argsDict["sn"] = self.sn - #Arnob trying to print flux - argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - #print("Hi",anb_seepage_flux) - #print("Hi Seepage Flux", self.coefficients.anb_seepage_flux) - - self.richards.invert(argsDict) - # self.timeIntegration.dt, - # self.u[0].femSpace.elementMaps.psi, - # self.u[0].femSpace.elementMaps.grad_psi, - # self.mesh.nodeArray, - # self.mesh.nodeVelocityArray, - # self.MOVING_DOMAIN, - # self.mesh.elementNodesArray, - # self.elementQuadratureWeights[('u',0)], - # self.u[0].femSpace.psi, - # self.u[0].femSpace.grad_psi, - # self.u[0].femSpace.psi, - # self.u[0].femSpace.grad_psi, - # #element boundary - # self.u[0].femSpace.elementMaps.psi_trace, - # self.u[0].femSpace.elementMaps.grad_psi_trace, - # self.elementBoundaryQuadratureWeights[('u',0)], - # self.u[0].femSpace.psi_trace, - # self.u[0].femSpace.grad_psi_trace, - # self.u[0].femSpace.psi_trace, - # self.u[0].femSpace.grad_psi_trace, - # self.u[0].femSpace.elementMaps.boundaryNormals, - # self.u[0].femSpace.elementMaps.boundaryJacobians, - # #physics - # self.mesh.nElements_global, - # self.ebqe['penalty'],#double* ebqe_penalty_ext, - # self.mesh.elementMaterialTypes,#int* elementMaterialTypes, - # self.coefficients.isSeepageFace, - # self.coefficients.sdInfo[(0,0)][0],#int* a_rowptr, - # self.coefficients.sdInfo[(0,0)][1],#int* a_colind, - # self.coefficients.rho,#double rho, - # self.coefficients.beta,#double beta, - # self.coefficients.gravity,#double* gravity, - # self.coefficients.vgm_alpha_types,#double* alpha, - # self.coefficients.vgm_n_types,#double* n, - # self.coefficients.thetaR_types,#double* thetaR, - # self.coefficients.thetaSR_types,#double* thetaSR, - # self.coefficients.Ksw_types,#double* KWs, - # False,#self.coefficients.useMetrics, - # self.timeIntegration.alpha_bdf, - # 0,#self.shockCapturing.lag, - # 0.0,#cek hack self.shockCapturing.shockCapturingFactor, - # 0.0,#self.coefficients.sc_uref, - # 0.0,#self.coefficients.sc_beta, - # self.u[0].femSpace.dofMap.l2g, - # self.l2g[0]['freeGlobal'], - # self.mesh.elementDiametersArray, - # degree_polynomial, - # self.sHigh, - # self.u_dof_old, - # self.q['velocity'],#self.coefficients.q_v, - # self.timeIntegration.m_tmp[0], - # self.q[('u',0)], - # self.timeIntegration.beta_bdf[0], - # self.q[('cfl',0)], - # self.edge_based_cfl, - # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff[0], - # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff_last[0], - # self.offset[0],self.stride[0], - # r, - # self.mesh.nExteriorElementBoundaries_global, - # self.mesh.exteriorElementBoundariesArray, - # self.mesh.elementBoundaryElementsArray, - # self.mesh.elementBoundaryLocalElementBoundariesArray, - # self.ebqe['velocity'],#self.coefficients.ebqe_v, - # self.numericalFlux.isDOFBoundary[0], - # self.numericalFlux.ebqe[('u',0)], - # self.ebqe[('advectiveFlux_bc_flag',0)], - # self.ebqe[('advectiveFlux_bc',0)], - # self.ebqe[('u',0)],#cek hack self.coefficients.ebqe_phi, - # 0.0,#cek hack self.coefficients.epsFact, - # self.ebqe[('u',0)], - # self.ebqe[('advectiveFlux',0)], - # # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION - # self.coefficients.cE, - # self.coefficients.cK, - # # PARAMETERS FOR LOG BASED ENTROPY FUNCTION - # self.coefficients.uL, - # self.coefficients.uR, - # # PARAMETERS FOR EDGE VISCOSITY - # len(rowptr) - 1, # num of DOFs - # len(Cx), # num of non-zero entries in the sparsity pattern - # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) - # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) - # self.csrRowIndeces[(0, 0)], # row indices (convenient for element loops) - # self.csrColumnOffsets[(0, 0)], # column indices (convenient for element loops) - # self.csrColumnOffsets_eb[(0, 0)], # indices for boundary terms - # # C matrices - # Cx, - # Cy, - # Cz, - # CTx, - # CTy, - # CTz, - # self.ML, - # self.delta_x_ij, - # # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - # self.coefficients.LUMPED_MASS_MATRIX, - # self.coefficients.STABILIZATION_TYPE, - # self.coefficients.ENTROPY_TYPE, - # # FLUX CORRECTED TRANSPORT - # self.dLow, - # self.fluxMatrix, - # self.uDotLow, - # self.uLow, - # self.dt_times_dC_minus_dL, - # self.min_s_bc, - # self.max_s_bc, - # self.quantDOFs) - #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] - #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf - #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] - #self.timeIntegration.calculateElementCoefficients(self.q) - #if self.forceStrongConditions:# - # for cj in range(len(self.dirichletConditionsForceDOF)):# - # for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): - # r[self.offset[cj]+self.stride[cj]*dofN] = 0 - #if self.stabilization: - # self.stabilization.accumulateSubgridMassHistory(self.q) - #logEvent("Global residual",level=9,data=r) - #self.nonlinear_function_evaluations += 1 - #if self.globalResidualDummy is None: - # self.globalResidualDummy = numpy.zeros(r.shape,'d') - def postStep(self, t, firstStep=False): - with open('seepage_flux_nnnn', "a") as f: - f.write("\n Time"+ ",\t" +"Seepage\n") - f.write(repr(t)+ ",\t" +repr(self.coefficients.anb_seepage_flux)) - def getJacobian(self,jacobian): - if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG - cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, - jacobian) - degree_polynomial = 1 - try: - degree_polynomial = self.u[0].femSpace.order - except: - pass - if self.delta_x_ij is None: - self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') - argsDict = cArgumentsDict.ArgumentsDict() - argsDict["dt"] = self.timeIntegration.dt - argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi - argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi - argsDict["mesh_dof"] = self.mesh.nodeArray - argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray - argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN - argsDict["mesh_l2g"] = self.mesh.elementNodesArray - argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] - argsDict["u_trial_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi - argsDict["u_test_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi - argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace - argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace - argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] - argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals - argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians - argsDict["nElements_global"] = self.mesh.nElements_global - argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] - argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, - argsDict["isSeepageFace"] = self.coefficients.isSeepageFace - argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] - argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] - argsDict["rho"] = self.coefficients.rho - argsDict["beta"] = self.coefficients.beta - argsDict["gravity"] = self.coefficients.gravity - argsDict["alpha"] = self.coefficients.vgm_alpha_types - argsDict["n"] = self.coefficients.vgm_n_types - argsDict["thetaR"] = self.coefficients.thetaR_types - argsDict["thetaSR"] = self.coefficients.thetaSR_types - argsDict["KWs"] = self.coefficients.Ksw_types - argsDict["useMetrics"] = 0.0 - argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf - argsDict["lag_shockCapturing"] = 0 - argsDict["shockCapturingDiffusion"] = 0.0 - argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g - argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] - argsDict["elementDiameter"] = self.mesh.elementDiametersArray - argsDict["degree_polynomial"] = degree_polynomial - argsDict["u_dof"] = self.u[0].dof - argsDict["velocity"] = self.q['velocity'] - argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] - argsDict["cfl"] = self.q[('cfl',0)] - argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] - argsDict["csrRowIndeces_u_u"] = self.csrRowIndeces[(0,0)] - argsDict["csrColumnOffsets_u_u"] = self.csrColumnOffsets[(0,0)] - argsDict["globalJacobian"] = jacobian.getCSRrepresentation()[2] - argsDict["delta_x_ij"] = self.delta_x_ij - argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global - argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray - argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray - argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray - argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] - argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] - argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] - argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] - argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] - argsDict["csrColumnOffsets_eb_u_u"] = self.csrColumnOffsets_eb[(0,0)] - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - - #arnob trying to calculate flux - #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - #Arnob trying to print flux - #argsDict["anb_seepage_flux"] = self.calculateResidual.anb_seepage_flux - - #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - #print("Hi Seepage Flux", self.coefficients.anb_seepage_flux) - #print("Hi Seepage Flux",anb_seepage_flux) - #print("The seepage is ", anb_seepage_flux) - - - - - self.calculateJacobian(argsDict) - if self.forceStrongConditions: - for dofN in list(self.dirichletConditionsForceDOF[0].DOFBoundaryConditionsDict.keys()): - global_dofN = self.offset[0]+self.stride[0]*dofN - self.nzval[np.where(self.colind == global_dofN)] = 0.0 #column - self.nzval[self.rowptr[global_dofN]:self.rowptr[global_dofN+1]] = 0.0 #row - zeroRow=True - for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]):#row - if (self.colind[i] == global_dofN): - self.nzval[i] = 1.0 - zeroRow = False - if zeroRow: - raise RuntimeError("Jacobian has a zero row because sparse matrix has no diagonal entry at row "+repr(global_dofN)+". You probably need add diagonal mass or reaction term") - #scaling = 1.0#probably want to add some scaling to match non-dirichlet diagonals in linear system - #for cj in range(self.nc): - # for dofN in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.keys()): - # global_dofN = self.offset[cj]+self.stride[cj]*dofN - # for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]): - # if (self.colind[i] == global_dofN): - # self.nzval[i] = scaling - # else: - # self.nzval[i] = 0.0 - logEvent("Jacobian ",level=10,data=jacobian) - #mwf decide if this is reasonable for solver statistics - self.nonlinear_function_jacobian_evaluations += 1 - return jacobian - def calculateElementQuadrature(self): - """ - Calculate the physical location and weights of the quadrature rules - and the shape information at the quadrature points. - - This function should be called only when the mesh changes. - """ - #self.u[0].femSpace.elementMaps.getValues(self.elementQuadraturePoints, - # self.q['x']) - self.u[0].femSpace.elementMaps.getBasisValuesRef(self.elementQuadraturePoints) - self.u[0].femSpace.elementMaps.getBasisGradientValuesRef(self.elementQuadraturePoints) - self.u[0].femSpace.getBasisValuesRef(self.elementQuadraturePoints) - self.u[0].femSpace.getBasisGradientValuesRef(self.elementQuadraturePoints) - self.coefficients.initializeElementQuadrature(self.timeIntegration.t,self.q) - if self.stabilization != None: - self.stabilization.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) - self.stabilization.initializeTimeIntegration(self.timeIntegration) - if self.shockCapturing != None: - self.shockCapturing.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) - def calculateElementBoundaryQuadrature(self): - pass - def calculateExteriorElementBoundaryQuadrature(self): - """ - Calculate the physical location and weights of the quadrature rules - and the shape information at the quadrature points on global element boundaries. - - This function should be called only when the mesh changes. - """ - # - #get physical locations of element boundary quadrature points - # - #assume all components live on the same mesh - self.u[0].femSpace.elementMaps.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.elementMaps.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.elementMaps.getValuesGlobalExteriorTrace(self.elementBoundaryQuadraturePoints, - self.ebqe['x']) - self.fluxBoundaryConditionsObjectsDict = dict([(cj,FluxBoundaryConditions(self.mesh, - self.nElementBoundaryQuadraturePoints_elementBoundary, - self.ebqe[('x')], - getAdvectiveFluxBoundaryConditions=self.advectiveFluxBoundaryConditionsSetterDict[cj], - getDiffusiveFluxBoundaryConditions=self.diffusiveFluxBoundaryConditionsSetterDictDict[cj])) - for cj in list(self.advectiveFluxBoundaryConditionsSetterDict.keys())]) - self.coefficients.initializeGlobalExteriorElementBoundaryQuadrature(self.timeIntegration.t,self.ebqe) - #argsDict = cArgumentsDict.ArgumentsDict() - #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - #print("Hi", self.coefficients.anb_seepage_flux) - - #print("The seepage is ", anb_seepage_flux) - def estimate_mt(self): - pass - def calculateSolutionAtQuadrature(self): - pass - def calculateAuxiliaryQuantitiesAfterStep(self): - pass - def postStep(self, t, firstStep=False): - with open('seepage_flux_nnnnk', "a") as f: - f.write("\n Time"+ ",\t" +"Seepage\n") - f.write(repr(t)+ ",\t" +repr(self.coefficients.anb_seepage_flux)) - - - -#argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux -#anb_seepage_flux= self.coefficients.anb_seepage_flux -#print("Hi",anb_seepage_flux) - - -#print("Hello from the python file", self.coefficients.anb_seepage_flux) diff --git a/richards_fct/richards/edit/Richards_fct.h b/richards_fct/richards/edit/Richards_fct.h deleted file mode 100644 index 7eda28d4f6..0000000000 --- a/richards_fct/richards/edit/Richards_fct.h +++ /dev/null @@ -1,3174 +0,0 @@ -#ifndef Richards_H -#define Richards_H -#include -#include -#include -#include "CompKernel.h" -#include "ModelFactory.h" -#include "../mprans/ArgumentsDict.h" -#include "xtensor-python/pyarray.hpp" -#define nnz nSpace - -namespace py = pybind11; -#define POWER_SMOOTHNESS_INDICATOR 2 -#define IS_BETAij_ONE 0 -#define GLOBAL_FCT 0 -namespace proteus -{ - // Power entropy // - inline double ENTROPY(const double& phi, const double& phiL, const double& phiR){ - return 1./2.*std::pow(fabs(phi),2.); - } - inline double DENTROPY(const double& phi, const double& phiL, const double& phiR){ - return fabs(phi)*(phi>=0 ? 1 : -1); - } - // Log entropy // for level set from 0 to 1 - inline double ENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ - return std::log(fabs((phi-phiL)*(phiR-phi))+1E-14); - } - inline double DENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ - return (phiL+phiR-2*phi)*((phi-phiL)*(phiR-phi)>=0 ? 1 : -1)/(fabs((phi-phiL)*(phiR-phi))+1E-14); - } -} - -namespace proteus -{ - class Richards_base - { - //The base class defining the interface - public: - virtual ~Richards_base(){} - virtual void calculateResidual(arguments_dict& args)=0; - virtual void calculateJacobian(arguments_dict& args)=0; - virtual void invert(arguments_dict& args)=0; - virtual void FCTStep(arguments_dict& args)=0; - virtual void kth_FCT_step(arguments_dict& args)=0; - virtual void calculateResidual_entropy_viscosity(arguments_dict& args)=0; - virtual void calculateMassMatrix(arguments_dict& args)=0; - }; - - template - class Richards : public Richards_base - { - public: - const int nDOF_test_X_trial_element; - CompKernelType ck; - Richards(): - nDOF_test_X_trial_element(nDOF_test_element*nDOF_trial_element), - ck() - {} - inline - void evaluateCoefficients(const int rowptr[nSpace], - const int colind[nnz], - const double rho, - const double beta, - const double gravity[nSpace], - const double alpha, - const double n_vg, - const double thetaR, - const double thetaSR, - const double KWs[nnz], - const double& u, - double& m, - double& dm, - double f[nSpace], - double df[nSpace], - double a[nnz], - double da[nnz], - double as[nnz], - double& kr, - double& dkr) - { - const int nSpace2 = nSpace * nSpace; - double psiC; - double pcBar; - double pcBar_n; - double pcBar_nM1; - double pcBar_nM2; - double onePlus_pcBar_n; - double sBar; - double sqrt_sBar; - double DsBar_DpsiC; - double thetaW; - double DthetaW_DpsiC; - double vBar; - double vBar2; - double DvBar_DpsiC; - double KWr; - double DKWr_DpsiC; - double rho2 = rho * rho; - double thetaS; - double rhom; - double drhom; - double m_vg; - double pcBarStar; - double sqrt_sBarStar; - - psiC = -u; - m_vg = 1.0 - 1.0 / n_vg; - thetaS = thetaR + thetaSR; - if (psiC > 0.0) - { - pcBar = alpha * psiC; - pcBarStar = pcBar; - if (pcBar < 1.0e-8) - pcBarStar = 1.0e-8; - pcBar_nM2 = pow(pcBarStar, n_vg - 2); - pcBar_nM1 = pcBar_nM2 * pcBar; - pcBar_n = pcBar_nM1 * pcBar; - onePlus_pcBar_n = 1.0 + pcBar_n; - - sBar = pow(onePlus_pcBar_n, -m_vg); - /* using -mn = 1-n */ - DsBar_DpsiC = alpha * (1.0 - n_vg) * (sBar/onePlus_pcBar_n)*pcBar_nM1; - - vBar = 1.0-pcBar_nM1*sBar; - vBar2 = vBar*vBar; - DvBar_DpsiC = -alpha*(n_vg-1.0)*pcBar_nM2*sBar - pcBar_nM1*DsBar_DpsiC; - - thetaW = thetaSR*sBar + thetaR; - DthetaW_DpsiC = thetaSR * DsBar_DpsiC; - - sqrt_sBar = sqrt(sBar); - sqrt_sBarStar = sqrt_sBar; - if (sqrt_sBar < 1.0e-8) - sqrt_sBarStar = 1.0e-8; - KWr= sqrt_sBar*vBar2; - DKWr_DpsiC= ((0.5/sqrt_sBarStar)*DsBar_DpsiC*vBar2 - + - 2.0*sqrt_sBar*vBar*DvBar_DpsiC); - } - else - { - thetaW = thetaS; - DthetaW_DpsiC = 0.0; - KWr = 1.0; - DKWr_DpsiC = 0.0; - } - //slight compressibility - rhom = rho*exp(beta*u); - drhom = beta*rhom; - m = rhom*thetaW; - dm = -rhom*DthetaW_DpsiC+drhom*thetaW; - for (int I=0;I thetaS || thetaW <= thetaR) - { - //cek debug - std::cout<<"rho "< 0.0) - { - isDOFBoundary = 1; - bc_u = bc_u_seepage; - } - else - { - isDOFBoundary = 0; - flux = 0.0; - } - } - /* //set DOF flag and flux correctly if seepage face */ - /* if (isSeepageFace) */ - /* { */ - /* if (flux < 0.0 || u < bc_u_seepage) */ - /* { */ - /* isDOFBoundary = 0; */ - /* flux = 0.0; */ - /* } */ - /* else */ - /* { */ - /* isDOFBoundary = 1; */ - /* bc_u = bc_u_seepage; */ - /* } */ - /* } */ - /* //Dirichlet penalty */ - /* if (isDOFBoundary) */ - /* flux += penalty*(u-bc_u); */ - } - else - flux = bc_flux; - } - - void exteriorNumericalFluxJacobian(const int rowptr[nSpace], - const int colind[nnz], - const int isDOFBoundary, - const double n[nSpace], - const double K[nnz], - const double dK[nnz], - const double grad_psi[nSpace], - const double grad_v[nSpace], - const double dK_rho_g[nSpace], - const double v, - const double penalty, - double& fluxJacobian) - { - if (isDOFBoundary) - { - fluxJacobian = 0.0; - for(int I=0;I& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - double sc_uref = args.scalar("sc_uref"); - double sc_alpha = args.scalar("sc_alpha"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& u_dof_old = args.array("u_dof_old"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m = args.array("q_m"); - xt::pyarray& q_u = args.array("q_u"); - xt::pyarray& q_dV = args.array("q_dV"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - int offset_u = args.scalar("offset_u"); - int stride_u = args.scalar("stride_u"); - xt::pyarray& globalResidual = args.array("globalResidual"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& ebqe_phi = args.array("ebqe_phi"); - double epsFact = args.scalar("epsFact"); - xt::pyarray& ebqe_u = args.array("ebqe_u"); - xt::pyarray& ebqe_flux = args.array("ebqe_flux"); - // PARAMETERS FOR EDGE BASED STABILIZATION - double cE = args.scalar("cE"); - double cK = args.scalar("cK"); - // PARAMETERS FOR LOG BASED ENTROPY FUNCTION - double uL = args.scalar("uL"); - double uR = args.scalar("uR"); - // PARAMETERS FOR EDGE VISCOSITY - int numDOFs = args.scalar("numDOFs"); - int NNZ = args.scalar("NNZ"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); - xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); - xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); - xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); - // C matrices - xt::pyarray& Cx = args.array("Cx"); - xt::pyarray& Cy = args.array("Cy"); - xt::pyarray& Cz = args.array("Cz"); - xt::pyarray& CTx = args.array("CTx"); - xt::pyarray& CTy = args.array("CTy"); - xt::pyarray& CTz = args.array("CTz"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); - int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); - // FOR FCT - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& fluxMatrix = args.array("fluxMatrix"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); - xt::pyarray& min_s_bc = args.array("min_s_bc"); - xt::pyarray& max_s_bc = args.array("max_s_bc"); - // AUX QUANTITIES OF INTEREST - xt::pyarray& quantDOFs = args.array("quantDOFs"); - xt::pyarray& sLow = args.array("sLow"); - xt::pyarray& sn = args.array("sn"); - - assert(a_rowptr.data()[nSpace] == nnz); - assert(a_rowptr.data()[nSpace] == nSpace); - //cek should this be read in? - double Ct_sge = 4.0; - - //loop over elements to compute volume integrals and load them into element and global residual - // - //eN is the element index - //eN_k is the quadrature point index for a scalar - //eN_k_nSpace is the quadrature point index for a vector - //eN_i is the element test function index - //eN_j is the element trial function index - //eN_k_j is the quadrature point index for a trial function - //eN_k_i is the quadrature point index for a trial function - for(int eN=0;eN& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); - xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); - xt::pyarray& globalJacobian = args.array("globalJacobian"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - assert(a_rowptr.data()[nSpace] == nnz); - assert(a_rowptr.data()[nSpace] == nSpace); - double Ct_sge = 4.0; - - // - //loop over elements to compute volume integrals and load them into the element Jacobians and global Jacobian - // - for(int eN=0;eN& bc_mask = args.array("bc_mask"); - int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern - int numDOFs = args.scalar("numDOFs"); //number of DOFs - double dt = args.scalar("dt"); - xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) - - xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn - xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn - xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& limited_solution = args.array("limited_solution"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets - xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices - xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 - xt::pyarray& max_s_bc = args.array("max_s_bc"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int MONOLITHIC = args.scalar("MONOLITHIC"); - register double Rpos[numDOFs], Rneg[numDOFs]; - register double FluxCorrectionMatrix[NNZ]; - register double solL[numDOFs]; - register double sdot[numDOFs]; - ////////////////////// - //arnob adding the flux correction - /////////////////////// - //xt::pyarray& antidiffusive_term_with_limiter = args.array("antidiffusive_term_with_limiter"); - - - ////////////////// - // LOOP in DOFs // - ////////////////// - int ij=0; - for (int i=0; i 0) ? 1. : 0.); - Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); - - //update ij - ij+=1; - //std::cout<<"sdoti error"<0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])) - * FluxCorrectionMatrix[ij]; - alpha_dot = fmin(1.0, beta_ij*fabs(alpha_fA)/MassMatrix.data()[ij]/fmax(1.0e-8,fabs(sdoti-sdotj))); - if (MONOLITHIC == 0) - { - ith_Limiter_times_FluxCorrectionMatrix += alpha_fA; - } - else - { - ith_Limiter_times_FluxCorrectionMatrix += alpha_fA + (LUMPED_MASS_MATRIX == 1 ? 0. : 1.)*dt*alpha_dot*MassMatrix.data()[ij]*(sdoti-sdotj); - } - //update ij - ij+=1; - } - limited_solution.data()[i] = solL[i] + 1./lumped_mass_matrix.data()[i]*ith_Limiter_times_FluxCorrectionMatrix*bc_mask[i]; - //antidiffusive_term_with_limiter.data()[i]= ith_Limiter_times_FluxCorrectionMatrix; - ////////////////////// - //arnob adding the flux correction - /////////////////////// - //xt::pyarray& antidiffusive_term_with_limiter = args.array("antidiffusive_term_with_limiter"); - - } - } - - void kth_FCT_step(arguments_dict& args) - { - int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern - int numDOFs = args.scalar("numDOFs"); //number of DOFs - int num_fct_iter = args.scalar("num_fct_iter"); - double dt = args.scalar("dt"); - xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) - xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn - xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn - xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& solLim = args.array("limited_solution"); - xt::pyarray& MC = args.array("MC"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& FluxMatrix = args.array("FluxMatrix"); - xt::pyarray& limitedFlux = args.array("limited_Flux"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets - xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices - xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 - xt::pyarray& max_s_bc = args.array("max_s_bc"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int MONOLITHIC = args.scalar("MONOLITHIC"); - register double Rpos[numDOFs], Rneg[numDOFs]; - int ij=0; - - - - - - ////////////////////////////////////////////////////// - // ********** COMPUTE LOW ORDER SOLUTION ********** // - ////////////////////////////////////////////////////// - if (num_fct_iter == 0) - { // No FCT for global bounds - for (int i=0; i 0) ? 1. : 0.); - // update ij - ij+=1; - } - // compute Q vectors - double mi = ML.data()[i]; - double solLimi = solLim.data()[i]; - double Qposi = mi*(maxi-solLimi); - // compute R vectors - Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - } - ij=0; - for (int i=0; i0 ? Rposi : Rpos[j]); - // compute limited flux - ith_Limiter_times_FluxCorrectionMatrix += Lij*Fluxij; - - // update limited flux - limitedFlux.data()[ij] = Lij*Fluxij; - - //update FluxMatrix - FluxMatrix.data()[ij] = Fluxij; - - //update ij - ij+=1; - } - - //update limited solution - double mi = ML.data()[i]; - solLim.data()[i] += 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; - //arnob edit - - - } - } - } - - // ***************************************** // - // ********** HIGH ORDER SOLUTION ********** // - // ***************************************** // - ij=0; - for (int i=0; i 0 ? 1. : 0.); - Pnegi += fij * (fij < 0 ? 1. : 0.); - //update ij - ij+=1; - } - // compute Q vectors // - double mi = ML.data()[i]; - double Qposi = mi*(maxi-solLim.data()[i]); - double Qnegi = mi*(mini-solLim.data()[i]); - // compute R vectors // - Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); - } - - // COMPUTE LIMITERS // - ij=0; - for (int i=0; i 0 ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j]); - // compute ith_limited_flux_correction - ith_limited_flux_correction += Lij*fij; - ij+=1; - } - double mi = ML.data()[i]; - solLim[i] += 1./mi*ith_limited_flux_correction; - } - } - - void calculateResidual_entropy_viscosity(arguments_dict& args) - { - xt::pyarray& globalJacobian = args.array("globalJacobian"); - double Theta = args.scalar("Theta"); - xt::pyarray& bc_mask = args.array("bc_mask"); - double dt = args.scalar("dt"); - xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - double sc_uref = args.scalar("sc_uref"); - double sc_alpha = args.scalar("sc_alpha"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& r_l2g = args.array("r_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - int degree_polynomial = args.scalar("degree_polynomial"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& u_dof_old = args.array("u_dof_old"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m = args.array("q_m"); - xt::pyarray& q_u = args.array("q_u"); - xt::pyarray& q_dV = args.array("q_dV"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - int offset_u = args.scalar("offset_u"); - int stride_u = args.scalar("stride_u"); - xt::pyarray& globalResidual = args.array("globalResidual"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& ebqe_phi = args.array("ebqe_phi"); - double epsFact = args.scalar("epsFact"); - xt::pyarray& ebqe_u = args.array("ebqe_u"); - xt::pyarray& ebqe_flux = args.array("ebqe_flux"); - // PARAMETERS FOR EDGE BASED STABILIZATION - double cE = args.scalar("cE"); - double cK = args.scalar("cK"); - // PARAMETERS FOR LOG BASED ENTROPY FUNCTION - double uL = args.scalar("uL"); - double uR = args.scalar("uR"); - // PARAMETERS FOR EDGE VISCOSITY - int numDOFs = args.scalar("numDOFs"); - int NNZ = args.scalar("NNZ"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); - xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); - xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); - xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); - // C matrices - xt::pyarray& Cx = args.array("Cx"); - xt::pyarray& Cy = args.array("Cy"); - xt::pyarray& Cz = args.array("Cz"); - xt::pyarray& CTx = args.array("CTx"); - xt::pyarray& CTy = args.array("CTy"); - xt::pyarray& CTz = args.array("CTz"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); - int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); - // FOR FCT - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& fluxMatrix = args.array("fluxMatrix"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); - xt::pyarray& min_s_bc = args.array("min_s_bc"); - xt::pyarray& max_s_bc = args.array("max_s_bc"); - // AUX QUANTITIES OF INTEREST - xt::pyarray& quantDOFs = args.array("quantDOFs"); - xt::pyarray& sLow = args.array("sLow"); - xt::pyarray& sn = args.array("sn"); - register double Rpos[numDOFs], Rneg[numDOFs]; - //register double FluxCorrectionMatrix[NNZ]; - // NOTE: This function follows a different (but equivalent) implementation of the smoothness based indicator than NCLS.h - // Allocate space for the transport matrices - // This is used for first order KUZMIN'S METHOD - register double TransportMatrix[NNZ],TransportMatrixConsistent[NNZ]; - register double TransportMatrixn[NNZ],TransportMatrixConsistentn[NNZ]; - std::valarray u_free_dof(numDOFs); - std::valarray u_free_dof_old(numDOFs); - std::valarray ML2(numDOFs); - for(int eN=0;eN= 0 && isFluxBoundary_u[ebNE_kb] != 1 ) //outflow. This is handled via the transport matrices. Then flux_ext=0 and dflux_ext!=0 */ - /* { */ - /* dflux_ext = flow; */ - /* flux_ext = 0; */ - /* // save external u */ - /* ebqe_u[ebNE_kb] = u_ext; */ - /* } */ - /* else // inflow. This is handled via the boundary integral. Then flux_ext!=0 and dflux_ext=0 */ - /* { */ - /* dflux_ext = 0; */ - /* // save external u */ - /* ebqe_u[ebNE_kb] = isDOFBoundary_u[ebNE_kb]*ebqe_bc_u_ext[ebNE_kb]+(1-isDOFBoundary_u[ebNE_kb])*u_ext; */ - /* if (isDOFBoundary_u[ebNE_kb] == 1) */ - /* flux_ext = ebqe_bc_u_ext[ebNE_kb]*flow; */ - /* else if (isFluxBoundary_u[ebNE_kb] == 1) */ - /* flux_ext = ebqe_bc_flux_u_ext[ebNE_kb]; */ - /* else */ - /* { */ - /* std::cout<<"warning: VOF open boundary with no external trace, setting to zero for inflow"<= 0.) - { - alpha_numerator_pos += alpha_num; - alpha_denominator_pos += alpha_num; - } - else - { - alpha_numerator_neg += alpha_num; - alpha_denominator_neg += fabs(alpha_num); - } - //update ij - ij+=1; - } - // scale g vector by lumped mass matrix - if (fabs(ML.data()[i] - ML2[i]) > 1.0e-16) - std::cout<<"ML "< 0.0) - // assert( (xi[I] - xj[I]) == delta_x_ij[offset*3+I]); - //gi_times_x += gi[I]*(xi[I]-xj[I]); - gi_times_x += gi[I]*delta_x_ij.data()[offset*3+I]; - } - // compute the positive and negative part of gi*(xi-xj) - SumPos += gi_times_x > 0 ? gi_times_x : 0; - SumNeg += gi_times_x < 0 ? gi_times_x : 0; - } - double sigmaPosi = fmin(1.,(fabs(SumNeg)+1E-15)/(SumPos+1E-15)); - double sigmaNegi = fmin(1.,(SumPos+1E-15)/(fabs(SumNeg)+1E-15)); - double alpha_numi = fabs(sigmaPosi*alpha_numerator_pos + sigmaNegi*alpha_numerator_neg); - double alpha_deni = sigmaPosi*alpha_denominator_pos + sigmaNegi*alpha_denominator_neg; - if (IS_BETAij_ONE == 1) - { - alpha_numi = fabs(alpha_numerator_pos + alpha_numerator_neg); - alpha_deni = alpha_denominator_pos + alpha_denominator_neg; - } - double alphai = alpha_numi/(alpha_deni+1E-15); - quantDOFs.data()[i] = alphai; - - if (POWER_SMOOTHNESS_INDICATOR==0) - psi[i] = 1.0; - else - psi[i] = std::pow(alphai,POWER_SMOOTHNESS_INDICATOR); //NOTE: they use alpha^2 in the paper - } - ///////////////////////////////////////////// - // ** LOOP IN DOFs FOR EDGE BASED TERMS ** // - ///////////////////////////////////////////// - ij=0; - for (int i=0; i Dissipation matrices as well. - double soli = u_free_dof[i]; // solution at time tn for the ith DOF - double solni = u_free_dof_old[i]; // solution at time tn for the ith DOF - for (int I=0;I& bc_mask = args.array("bc_mask"); - int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern - int numDOFs = args.scalar("numDOFs"); //number of DOFs - double dt = args.scalar("dt"); - xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) - - xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn - xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn - xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& limited_solution = args.array("limited_solution"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets - xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices - xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 - xt::pyarray& max_s_bc = args.array("max_s_bc"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int MONOLITHIC = args.scalar("MONOLITHIC"); - register double Rpos[numDOFs], Rneg[numDOFs]; - register double FluxCorrectionMatrix[NNZ]; - register double solL[numDOFs]; - register double sdot[numDOFs]; - ////////////////////// - //arnob adding the flux correction - /////////////////////// - //xt::pyarray& antidiffusive_term_with_limiter = args.array("antidiffusive_term_with_limiter"); - - - ////////////////// - // LOOP in DOFs // - ////////////////// - int ij=0; - for (int i=0; i 0) ? 1. : 0.); - Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); - - //update ij - ij+=1; - //std::cout<<"sdoti error"<0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])) - * FluxCorrectionMatrix[ij]; - alpha_dot = fmin(1.0, beta_ij*fabs(alpha_fA)/MassMatrix.data()[ij]/fmax(1.0e-8,fabs(sdoti-sdotj))); - if (MONOLITHIC == 0) - { - ith_Limiter_times_FluxCorrectionMatrix += alpha_fA; - } - else - { - ith_Limiter_times_FluxCorrectionMatrix += alpha_fA + (LUMPED_MASS_MATRIX == 1 ? 0. : 1.)*dt*alpha_dot*MassMatrix.data()[ij]*(sdoti-sdotj); - } - //update ij - ij+=1; - } - limited_solution.data()[i] = solL[i] + 1./lumped_mass_matrix.data()[i]*ith_Limiter_times_FluxCorrectionMatrix*bc_mask[i]; - //antidiffusive_term_with_limiter.data()[i]= ith_Limiter_times_FluxCorrectionMatrix; - ////////////////////// - //arnob adding the flux correction - /////////////////////// - //xt::pyarray& antidiffusive_term_with_limiter = args.array("antidiffusive_term_with_limiter"); - - //} - - - globalResidual.data()[i] = (mi*(m - mn)/dt - ith_flux_term)*bc_mask.data()[i]; ;//+ antidiffusive_term_with_limiter.data()[i])*bc_mask.data()[i];//cek should introduce mn,mnp1 or somethign clearer - globalJacobian.data()[ii] += bc_mask.data()[i]*(mi*dm/dt + J_ii) + (1.0-bc_mask.data()[i]); - - //if (GLOBAL_FCT==1) - //{ - //limited_solution.data()[i] = solL[i] + 1./lumped_mass_matrix.data()[i]*ith_Limiter_times_FluxCorrectionMatrix*bc_mask[i]; - //antidiffusive_term_with_limiter.data()[i]= ith_Limiter_times_FluxCorrectionMatrix - //globalResidual.data()[i] = (mi*(m - mn)/dt - ith_flux_term)*bc_mask.data()[i]; - //globalResidual.data()[i] = (mi*(m - mn)/dt - ith_flux_term + ith_Limiter_times_FluxCorrectionMatrix)*bc_mask.data()[i]; - - //+ith_Limiter_times_FluxCorrectionMatrix; - //} - //else - //{ - //globalResidual.data()[i] = (mi*(m - mn)/dt - ith_flux_term)*bc_mask.data()[i]; - } - - if (false) - { - //cek debug - //std::cout<<"dt*divergence "< mMax) - { - std::cout<<"mass out of bounds "< 0) ? 1. : 0.); - // Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); - // ij+=1; - // } - // double mi = ML[i]; - // double solni = u_dof_old[i]; - // double Qposi = mi*(maxi-solni); - // double Qnegi = mi*(mini-solni); - - //std::cout << Qposi << std::endl; - // Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - // Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); - - //if (Rpos[i] < 0) - //{ - // std::cout << mi << "\t" << maxi << "\t" << solni << std::endl; - // std::cout << Qposi << "\t" << Pposi << std::endl; - // std::cout << Rpos[i] << std::endl; - //abort(); - //} - //} - - //ij=0; - //for (int i=0; i 1.0 || Rposi < 0.0) - //std::cout << "Rposi: " << Rposi << std::endl; - //if (Rnegi > 1.0 || Rnegi < 0.0) - //std::cout << "Rnegi: " << Rnegi << std::endl; - - // LOOP OVER THE SPARSITY PATTERN (j-LOOP)// - // for (int offset=csrRowIndeces_DofLoops.data()[i]; - // offset0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])); - // //Lij=0.0; - // ith_Limiter_times_FluxCorrectionMatrix += Lij*FluxCorrectionMatrix[ij]; - // //update ij - // ij+=1; - // } - // double mi = ML[i]; - // double solni = u_dof_old[i]; - // globalResidual[i] = solni + 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; - //} - - } - - void invert(arguments_dict& args) - { - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - xt::pyarray& globalResidual = args.array("globalResidual"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - int numDOFs = args.scalar("numDOFs"); - for (int i=0; i mMax) - { - std::cout<<"mass out of bounds "<("dt"); - xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - //element boundary - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - //physics - int nElements_global = args.scalar("nElements_global"); - //new - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - //end new - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& r_l2g = args.array("r_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - int degree_polynomial = args.scalar("degree_polynomial"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); - xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); - xt::pyarray& globalJacobian = args.array("globalJacobian"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - //std::cout<<"ndjaco address "<(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - else if (nSpaceIn == 2) - return proteus::chooseAndAllocateDiscretization2D(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - else - { - assert(nSpaceIn == 3); - return proteus::chooseAndAllocateDiscretization(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - } - } -};//proteus -#endif \ No newline at end of file diff --git a/richards_fct/richards/edit/Richards_n.py b/richards_fct/richards/edit/Richards_n.py deleted file mode 100755 index 450ab93293..0000000000 --- a/richards_fct/richards/edit/Richards_n.py +++ /dev/null @@ -1,1840 +0,0 @@ -from __future__ import division -from builtins import range -from past.utils import old_div -import proteus -from .cRichards import * -import numpy as np -from proteus.Transport import OneLevelTransport -from proteus.Transport import TC_base, NonlinearEquation, logEvent, memory -from proteus.Transport import FluxBoundaryConditions, Comm, cfemIntegrals -from proteus.Transport import DOFBoundaryConditions, Quadrature -from proteus.mprans import cArgumentsDict -from proteus.LinearAlgebraTools import SparseMat -from proteus import TimeIntegration -from proteus.NonlinearSolvers import ExplicitLumpedMassMatrixForRichards - -class ThetaScheme(TimeIntegration.BackwardEuler): - def __init__(self,transport,integrateInterpolationPoints=False): - self.transport=transport - TimeIntegration.BackwardEuler.__init__(self,transport, integrateInterpolationPoints) - def updateTimeHistory(self,resetFromDOF=False): - TimeIntegration.BackwardEuler.updateTimeHistory(self,resetFromDOF) - self.transport.u_dof_old[:] = self.u -class RKEV(TimeIntegration.SSP): - from proteus import TimeIntegration - """ - Wrapper for SSPRK time integration using EV - - ... more to come ... - """ - - def __init__(self, transport, timeOrder=1, runCFL=0.1, integrateInterpolationPoints=False): - TimeIntegration.SSP.__init__(self, transport, integrateInterpolationPoints=integrateInterpolationPoints) - self.runCFL = runCFL - self.dtLast = None - self.isAdaptive = True - # About the cfl - assert transport.coefficients.STABILIZATION_TYPE > 0, "SSP method just works for edge based EV methods; i.e., STABILIZATION_TYPE>0" - assert hasattr(transport, 'edge_based_cfl'), "No edge based cfl defined" - self.cfl = transport.edge_based_cfl - # Stuff particular for SSP - self.timeOrder = timeOrder # order of approximation - self.nStages = timeOrder # number of stages total - self.lstage = 0 # last stage completed - # storage vectors - self.u_dof_last = {} - # per component stage values, list with array at each stage - self.u_dof_stage = {} - for ci in range(self.nc): - if ('m', ci) in transport.q: - self.u_dof_last[ci] = transport.u[ci].dof.copy() - self.u_dof_stage[ci] = [] - for k in range(self.nStages + 1): - self.u_dof_stage[ci].append(transport.u[ci].dof.copy()) - #print() - - - # def set_dt(self, DTSET): - # self.dt = DTSET # don't update t - def choose_dt(self): - comm = Comm.get() - maxCFL = 1.0e-6 - maxCFL = max(maxCFL, comm.globalMax(self.cfl.max())) - self.dt = old_div(self.runCFL, maxCFL) - if self.dtLast is None: - self.dtLast = self.dt - self.t = self.tLast + self.dt - self.substeps = [self.t for i in range(self.nStages)] # Manuel is ignoring different time step levels for now - #print("Hi, This is Arnob") - - - def initialize_dt(self, t0, tOut, q): - """ - Modify self.dt - """ - self.tLast = t0 - self.choose_dt() - self.t = t0 + self.dt - - def setCoefficients(self): - """ - beta are all 1's here - mwf not used right now - """ - self.alpha = np.zeros((self.nStages, self.nStages), 'd') - self.dcoefs = np.zeros((self.nStages), 'd') - - def updateStage(self): - """ - Need to switch to use coefficients - """ - self.lstage += 1 - assert self.timeOrder in [1, 2, 3] - assert self.lstage > 0 and self.lstage <= self.timeOrder - if self.timeOrder == 3: - if self.lstage == 1: - logEvent("First stage of SSP33 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - # update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] - elif self.lstage == 2: - logEvent("Second stage of SSP33 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - self.u_dof_stage[ci][self.lstage] *= old_div(1., 4.) - self.u_dof_stage[ci][self.lstage] += 3. / 4. * self.u_dof_last[ci] - # Update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] - elif self.lstage == 3: - logEvent("Third stage of SSP33 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - self.u_dof_stage[ci][self.lstage] *= old_div(2.0, 3.0) - self.u_dof_stage[ci][self.lstage] += 1.0 / 3.0 * self.u_dof_last[ci] - # update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_last[ci] - # update solution to u[0].dof - self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] - elif self.timeOrder == 2: - if self.lstage == 1: - logEvent("First stage of SSP22 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - # Update u_dof_old - self.transport.u_dof_old[:] = self.transport.u[ci].dof - elif self.lstage == 2: - logEvent("Second stage of SSP22 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - self.u_dof_stage[ci][self.lstage][:] *= old_div(1., 2.) - self.u_dof_stage[ci][self.lstage][:] += 1. / 2. * self.u_dof_last[ci] - # update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_last[ci] - # update solution to u[0].dof - self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] - else: - assert self.timeOrder == 1 - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof[:] - self.transport.u_dof_old[:] = self.transport.u[ci].dof - #self.print("Hi, Arnob") - - def initializeTimeHistory(self, resetFromDOF=True): - """ - Push necessary information into time history arrays - """ - for ci in range(self.nc): - self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] - for k in range(self.nStages): - self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] - - def updateTimeHistory(self, resetFromDOF=False): - """ - assumes successful step has been taken - """ - - self.t = self.tLast + self.dt - for ci in range(self.nc): - self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] - for k in range(self.nStages): - self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] - self.lstage = 0 - self.dtLast = self.dt - self.tLast = self.t - - def generateSubsteps(self, tList): - """ - create list of substeps over time values given in tList. These correspond to stages - """ - self.substeps = [] - tLast = self.tLast - for t in tList: - dttmp = t - tLast - self.substeps.extend([tLast + dttmp for i in range(self.nStages)]) - tLast = t - - def resetOrder(self, order): - """ - initialize data structures for stage updges - """ - self.timeOrder = order # order of approximation - self.nStages = order # number of stages total - self.lstage = 0 # last stage completed - # storage vectors - # per component stage values, list with array at each stage - self.u_dof_stage = {} - for ci in range(self.nc): - if ('m', ci) in self.transport.q: - self.u_dof_stage[ci] = [] - for k in range(self.nStages + 1): - self.u_dof_stage[ci].append(self.transport.u[ci].dof.copy()) - self.substeps = [self.t for i in range(self.nStages)] - - def setFromOptions(self, nOptions): - """ - allow classes to set various numerical parameters - """ - if 'runCFL' in dir(nOptions): - self.runCFL = nOptions.runCFL - flags = ['timeOrder'] - for flag in flags: - if flag in dir(nOptions): - val = getattr(nOptions, flag) - setattr(self, flag, val) - if flag == 'timeOrder': - self.resetOrder(self.timeOrder) - - - -class Coefficients(proteus.TransportCoefficients.TC_base): - """ - version of Re where element material type id's used in evals - """ - from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2 - from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchten_sd_het - def __init__(self, - nd, - Ksw_types, - vgm_n_types, - vgm_alpha_types, - thetaR_types, - thetaSR_types, - gravity, - density, - beta, - diagonal_conductivity=True, - getSeepageFace=None, - # FOR EDGE BASED EV - STABILIZATION_TYPE=0, - ENTROPY_TYPE=2, # logarithmic - LUMPED_MASS_MATRIX=False, - MONOLITHIC=True, - FCT=True, - num_fct_iter=1, - # FOR ENTROPY VISCOSITY - cE=1.0, - uL=0.0, - uR=1.0, - # FOR ARTIFICIAL COMPRESSION - cK=1.0, - # OUTPUT quantDOFs - outputQuantDOFs=False, ): - self.anb_seepage_flux= 0.00 - #self.anb_seepage_flux_n =0.0 - variableNames=['pressure_head'] - nc=1 - mass={0:{0:'nonlinear'}} - advection={0:{0:'nonlinear'}} - diffusion={0:{0:{0:'nonlinear'}}} - potential={0:{0:'u'}} - reaction={0:{0:'linear'}} - hamiltonian={} - self.getSeepageFace=getSeepageFace - self.gravity=gravity - self.rho = density - self.beta=beta - self.vgm_n_types = vgm_n_types - self.vgm_alpha_types = vgm_alpha_types - self.thetaR_types = thetaR_types - self.thetaSR_types = thetaSR_types - self.elementMaterialTypes = None - self.exteriorElementBoundaryTypes = None - self.materialTypes_q = None - self.materialTypes_ebq = None - self.materialTypes_ebqe = None - self.nd = nd - self.nMaterialTypes = len(thetaR_types) - self.q = {}; self.ebqe = {}; self.ebq = {}; self.ebq_global={} - #try to allow some flexibility in input of permeability/conductivity tensor - self.diagonal_conductivity = diagonal_conductivity - self.Ksw_types_in = Ksw_types - if self.diagonal_conductivity: - sparseDiffusionTensors = {(0,0):(np.arange(self.nd+1,dtype='i'), - np.arange(self.nd,dtype='i'))} - - assert len(Ksw_types.shape) in [1,2], "if diagonal conductivity true then Ksw_types scalar or vector of diagonal entries" - #allow scalar input Ks - if len(Ksw_types.shape)==1: - self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd),'d') - for I in range(self.nd): - self.Ksw_types[:,I] = Ksw_types - else: - self.Ksw_types = Ksw_types - else: #full - sparseDiffusionTensors = {(0,0):(np.arange(self.nd**2+1,step=self.nd,dtype='i'), - np.array([list(range(self.nd)) for row in range(self.nd)],dtype='i'))} - assert len(Ksw_types.shape) in [1,2], "if full tensor conductivity true then Ksw_types scalar or 'flattened' row-major representation of entries" - if len(Ksw_types.shape)==1: - self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd**2),'d') - for I in range(self.nd): - self.Ksw_types[:,I*self.nd+I] = Ksw_types - else: - assert Ksw_types.shape[1] == self.nd**2 - self.Ksw_types = Ksw_types - # EDGE BASED (AND ENTROPY) VISCOSITY - self.LUMPED_MASS_MATRIX = LUMPED_MASS_MATRIX - self.MONOLITHIC = MONOLITHIC - self.STABILIZATION_TYPE = STABILIZATION_TYPE - self.ENTROPY_TYPE = ENTROPY_TYPE - self.FCT = FCT - self.num_fct_iter=num_fct_iter - self.uL = uL - self.uR = uR - self.cK = cK - self.forceStrongConditions = True - self.cE = cE - self.outputQuantDOFs = outputQuantDOFs - TC_base.__init__(self, - nc, - mass, - advection, - diffusion, - potential, - reaction, - hamiltonian, - variableNames, - sparseDiffusionTensors = sparseDiffusionTensors, - useSparseDiffusion = True) - - def initializeMesh(self,mesh): - from proteus.SubsurfaceTransportCoefficients import BlockHeterogeneousCoefficients - self.elementMaterialTypes,self.exteriorElementBoundaryTypes,self.elementBoundaryTypes = BlockHeterogeneousCoefficients(mesh).initializeMaterialTypes() - #want element boundary material types for evaluating heterogeneity - #not boundary conditions - self.isSeepageFace = np.zeros((mesh.nExteriorElementBoundaries_global),'i') - if self.getSeepageFace != None: - for ebNE in range(mesh.nExteriorElementBoundaries_global): - #mwf missing ebNE-->ebN? - ebN = mesh.exteriorElementBoundariesArray[ebNE] - #print "eb flag",mesh.elementBoundaryMaterialTypes[ebN] - #print("Hi, Arnob") - #print self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) - self.isSeepageFace[ebNE] = self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) - #print (self.isSeepageFace) - def initializeElementQuadrature(self,t,cq): - self.materialTypes_q = self.elementMaterialTypes - self.q_shape = cq[('u',0)].shape - #self.anb_seepage_flux= anb_seepage_flux - #print("The seepage is ", anb_seepage_flux) -# cq['Ks'] = np.zeros(self.q_shape,'d') -# for k in range(self.q_shape[1]): -# cq['Ks'][:,k] = self.Ksw_types[self.elementMaterialTypes,0] - self.q[('vol_frac',0)] = np.zeros(self.q_shape,'d') - def initializeElementBoundaryQuadrature(self,t,cebq,cebq_global): - self.materialTypes_ebq = np.zeros(cebq[('u',0)].shape[0:2],'i') - self.ebq_shape = cebq[('u',0)].shape - for ebN_local in range(self.ebq_shape[1]): - self.materialTypes_ebq[:,ebN_local] = self.elementMaterialTypes - self.ebq[('vol_frac',0)] = np.zeros(self.ebq_shape,'d') - - def initializeGlobalExteriorElementBoundaryQuadrature(self,t,cebqe): - self.materialTypes_ebqe = self.exteriorElementBoundaryTypes - self.ebqe_shape = cebqe[('u',0)].shape - self.ebqe[('vol_frac',0)] = np.zeros(self.ebqe_shape,'d') - # - - - def evaluate(self,t,c): - if c[('u',0)].shape == self.q_shape: - materialTypes = self.materialTypes_q - vol_frac = self.q[('vol_frac',0)] - elif c[('u',0)].shape == self.ebqe_shape: - materialTypes = self.materialTypes_ebqe - vol_frac = self.ebqe[('vol_frac',0)] - elif c[('u',0)].shape == self.ebq_shape: - materialTypes = self.materialTypes_ebq - vol_frac = self.ebq[('vol_frac',0)] - else: - assert False, "no materialType found to match c[('u',0)].shape= %s " % c[('u',0)].shape - self.conservativeHeadRichardsMualemVanGenuchten_sd_het(self.sdInfo[(0,0)][0], - self.sdInfo[(0,0)][1], - materialTypes, - self.rho, - self.beta, - self.gravity, - self.vgm_alpha_types, - self.vgm_n_types, - self.thetaR_types, - self.thetaSR_types, - self.Ksw_types, - c[('u',0)], - c[('m',0)], - c[('dm',0,0)], - c[('f',0)], - c[('df',0,0)], - c[('a',0,0)], - c[('da',0,0,0)], - vol_frac) - # print "Picard---------------------------------------------------------------" - # c[('df',0,0)][:] = 0.0 - # c[('da',0,0,0)][:] = 0.0 -# self.conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2(materialTypes, -# self.rho, -# self.beta, -# self.gravity, -# self.vgm_alpha_types, -# self.vgm_n_types, -# self.thetaR_types, -# self.thetaSR_types, -# self.Ksw_types, -# c[('u',0)], -# c[('m',0)], -# c[('dm',0,0)], -# c[('f',0)], -# c[('df',0,0)], -# c[('a',0,0)], -# c[('da',0,0,0)]) - #mwf debug - if (np.isnan(c[('da',0,0,0)]).any() or - np.isnan(c[('a',0,0)]).any() or - np.isnan(c[('df',0,0)]).any() or - np.isnan(c[('f',0)]).any() or - np.isnan(c[('u',0)]).any() or - np.isnan(c[('m',0)]).any() or - np.isnan(c[('dm',0,0)]).any()): - import pdb - pdb.set_trace() - - def postStep(self, t, firstStep=False): - #anb_seepage_flux_n[:]= self.anb_seepage_flux - with open('seepage_flux_nn', "a") as f: - f.write("\n Time"+ ",\t" +"Seepage\n") - f.write(repr(t)+ ",\t" +repr(self.anb_seepage_flux)) - - - -class LevelModel(proteus.Transport.OneLevelTransport): - nCalls=0 - def __init__(self, - uDict, - phiDict, - testSpaceDict, - matType, - dofBoundaryConditionsDict, - dofBoundaryConditionsSetterDict, - coefficients, - elementQuadrature, - elementBoundaryQuadrature, - fluxBoundaryConditionsDict=None, - advectiveFluxBoundaryConditionsSetterDict=None, - diffusiveFluxBoundaryConditionsSetterDictDict=None, - stressTraceBoundaryConditionsSetterDict=None, - stabilization=None, - shockCapturing=None, - conservativeFluxDict=None, - numericalFluxType=None, - TimeIntegrationClass=None, - massLumping=False, - reactionLumping=False, - options=None, - name='defaultName', - reuse_trial_and_test_quadrature=True, - sd = True, - movingDomain=False, - bdyNullSpace=False): - self.bdyNullSpace=bdyNullSpace - # - #set the objects describing the method and boundary conditions - # - self.movingDomain=movingDomain - self.tLast_mesh=None - # - self.name=name - self.sd=sd - self.Hess=False - self.lowmem=True - self.timeTerm=True#allow turning off the time derivative - #self.lowmem=False - self.testIsTrial=True - self.phiTrialIsTrial=True - self.u = uDict - self.ua = {}#analytical solutions - self.phi = phiDict - self.dphi={} - self.matType = matType - #mwf try to reuse test and trial information across components if spaces are the same - self.reuse_test_trial_quadrature = reuse_trial_and_test_quadrature#True#False - if self.reuse_test_trial_quadrature: - for ci in range(1,coefficients.nc): - assert self.u[ci].femSpace.__class__.__name__ == self.u[0].femSpace.__class__.__name__, "to reuse_test_trial_quad all femSpaces must be the same!" - self.u_dof_old = None - ## Simplicial Mesh - self.mesh = self.u[0].femSpace.mesh #assume the same mesh for all components for now - self.testSpace = testSpaceDict - self.dirichletConditions = dofBoundaryConditionsDict - self.dirichletNodeSetList=None #explicit Dirichlet conditions for now, no Dirichlet BC constraints - self.coefficients = coefficients - self.coefficients.initializeMesh(self.mesh) - self.nc = self.coefficients.nc - self.stabilization = stabilization - self.shockCapturing = shockCapturing - self.conservativeFlux = conservativeFluxDict #no velocity post-processing for now - self.fluxBoundaryConditions=fluxBoundaryConditionsDict - self.advectiveFluxBoundaryConditionsSetterDict=advectiveFluxBoundaryConditionsSetterDict - self.diffusiveFluxBoundaryConditionsSetterDictDict = diffusiveFluxBoundaryConditionsSetterDictDict - #determine whether the stabilization term is nonlinear - self.stabilizationIsNonlinear = False - #cek come back - if self.stabilization != None: - for ci in range(self.nc): - if ci in coefficients.mass: - for flag in list(coefficients.mass[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.advection: - for flag in list(coefficients.advection[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.diffusion: - for diffusionDict in list(coefficients.diffusion[ci].values()): - for flag in list(diffusionDict.values()): - if flag != 'constant': - self.stabilizationIsNonlinear=True - if ci in coefficients.potential: - for flag in list(coefficients.potential[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.reaction: - for flag in list(coefficients.reaction[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.hamiltonian: - for flag in list(coefficients.hamiltonian[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - #determine if we need element boundary storage - self.elementBoundaryIntegrals = {} - for ci in range(self.nc): - self.elementBoundaryIntegrals[ci] = ((self.conservativeFlux != None) or - (numericalFluxType != None) or - (self.fluxBoundaryConditions[ci] == 'outFlow') or - (self.fluxBoundaryConditions[ci] == 'mixedFlow') or - (self.fluxBoundaryConditions[ci] == 'setFlow')) - # - #calculate some dimensions - # - self.nSpace_global = self.u[0].femSpace.nSpace_global #assume same space dim for all variables - self.nDOF_trial_element = [u_j.femSpace.max_nDOF_element for u_j in list(self.u.values())] - self.nDOF_phi_trial_element = [phi_k.femSpace.max_nDOF_element for phi_k in list(self.phi.values())] - self.n_phi_ip_element = [phi_k.femSpace.referenceFiniteElement.interpolationConditions.nQuadraturePoints for phi_k in list(self.phi.values())] - self.nDOF_test_element = [femSpace.max_nDOF_element for femSpace in list(self.testSpace.values())] - self.nFreeDOF_global = [dc.nFreeDOF_global for dc in list(self.dirichletConditions.values())] - self.nVDOF_element = sum(self.nDOF_trial_element) - self.nFreeVDOF_global = sum(self.nFreeDOF_global) - # - NonlinearEquation.__init__(self,self.nFreeVDOF_global) - # - #build the quadrature point dictionaries from the input (this - #is just for convenience so that the input doesn't have to be - #complete) - # - elementQuadratureDict={} - elemQuadIsDict = isinstance(elementQuadrature,dict) - if elemQuadIsDict: #set terms manually - for I in self.coefficients.elementIntegralKeys: - if I in elementQuadrature: - elementQuadratureDict[I] = elementQuadrature[I] - - else: - elementQuadratureDict[I] = elementQuadrature['default'] - else: - for I in self.coefficients.elementIntegralKeys: - elementQuadratureDict[I] = elementQuadrature - if self.stabilization != None: - for I in self.coefficients.elementIntegralKeys: - if elemQuadIsDict: - if I in elementQuadrature: - elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature[I] - else: - elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature['default'] - else: - elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature - if self.shockCapturing != None: - for ci in self.shockCapturing.components: - if elemQuadIsDict: - if ('numDiff',ci,ci) in elementQuadrature: - elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature[('numDiff',ci,ci)] - #print("Hi, Arnob1") - #print(anb_seepage_flux) - else: - elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature['default'] - #print("Hi, Arnob2") - #print(anb_seepage_flux) - else: - elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature - print("Hi, Arnob3") - #print(anb_seepage_flux) - if massLumping: - for ci in list(self.coefficients.mass.keys()): - elementQuadratureDict[('m',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - print("Hi, Arnob4") - #print(anb_seepage_flux) - for I in self.coefficients.elementIntegralKeys: - elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - print("Hi, Arnob5") - #print(anb_seepage_flux) - if reactionLumping: - for ci in list(self.coefficients.mass.keys()): - elementQuadratureDict[('r',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - print("Hi, Arnob6") - #print(anb_seepage_flux) - for I in self.coefficients.elementIntegralKeys: - elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - print("Hi, Arnob7") - #print(anb_seepage_flux) - elementBoundaryQuadratureDict={} - if isinstance(elementBoundaryQuadrature,dict): #set terms manually - for I in self.coefficients.elementBoundaryIntegralKeys: - if I in elementBoundaryQuadrature: - elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature[I] - print("Hi, Arnob8") - #print(anb_seepage_flux) - else: - elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature['default'] - #print("Hi, Arnob9") - #print(anb_seepage_flux) - else: - for I in self.coefficients.elementBoundaryIntegralKeys: - elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature - print("Hi, Arnob10") - #print(anb_seepage_flux) - # - # find the union of all element quadrature points and - # build a quadrature rule for each integral that has a - # weight at each point in the union - #mwf include tag telling me which indices are which quadrature rule? - (self.elementQuadraturePoints,self.elementQuadratureWeights, - self.elementQuadratureRuleIndeces) = Quadrature.buildUnion(elementQuadratureDict) - self.nQuadraturePoints_element = self.elementQuadraturePoints.shape[0] - self.nQuadraturePoints_global = self.nQuadraturePoints_element*self.mesh.nElements_global - # - #Repeat the same thing for the element boundary quadrature - # - (self.elementBoundaryQuadraturePoints, - self.elementBoundaryQuadratureWeights, - self.elementBoundaryQuadratureRuleIndeces) = Quadrature.buildUnion(elementBoundaryQuadratureDict) - self.nElementBoundaryQuadraturePoints_elementBoundary = self.elementBoundaryQuadraturePoints.shape[0] - self.nElementBoundaryQuadraturePoints_global = (self.mesh.nElements_global* - self.mesh.nElementBoundaries_element* - self.nElementBoundaryQuadraturePoints_elementBoundary) -# if isinstance(self.u[0].femSpace,C0_AffineLinearOnSimplexWithNodalBasis): -# print self.nQuadraturePoints_element -# if self.nSpace_global == 3: -# assert(self.nQuadraturePoints_element == 5) -# elif self.nSpace_global == 2: -# assert(self.nQuadraturePoints_element == 6) -# elif self.nSpace_global == 1: -# assert(self.nQuadraturePoints_element == 3) -# -# print self.nElementBoundaryQuadraturePoints_elementBoundary -# if self.nSpace_global == 3: -# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) -# elif self.nSpace_global == 2: -# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) -# elif self.nSpace_global == 1: -# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 1) - - # - #storage dictionaries - self.scalars_element = set() - # - #simplified allocations for test==trial and also check if space is mixed or not - # - self.q={} - self.ebq={} - self.ebq_global={} - self.ebqe={} - self.phi_ip={} - self.edge_based_cfl = np.zeros(self.u[0].dof.shape)+100 - #mesh - #self.q['x'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,3),'d') - self.q[('dV_u', 0)] = (old_div(1.0, self.mesh.nElements_global)) * np.ones((self.mesh.nElements_global, self.nQuadraturePoints_element), 'd') - self.ebqe['x'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,3),'d') - self.q[('u',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') - self.q[('grad(u)',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') - self.q['velocity'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') - self.q[('m',0)] = self.q[('u',0)].copy() - self.q[('mt',0)] = self.q[('u',0)].copy() - self.q[('m_last',0)] = self.q[('u',0)].copy() - self.q[('m_tmp',0)] = self.q[('u',0)].copy() - self.q[('cfl',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') - self.q[('numDiff',0,0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') - self.ebqe[('u',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.ebqe[('grad(u)',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') - self.ebqe['velocity'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') - self.ebqe[('advectiveFlux_bc_flag',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'i') - self.ebqe[('advectiveFlux_bc',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.ebqe[('advectiveFlux',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.ebqe[('penalty')] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.points_elementBoundaryQuadrature= set() - self.scalars_elementBoundaryQuadrature= set([('u',ci) for ci in range(self.nc)]) - self.vectors_elementBoundaryQuadrature= set() - self.tensors_elementBoundaryQuadrature= set() - self.inflowBoundaryBC = {} - self.inflowBoundaryBC_values = {} - self.inflowFlux = {} - for cj in range(self.nc): - self.inflowBoundaryBC[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,),'i') - self.inflowBoundaryBC_values[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nDOF_trial_element[cj]),'d') - self.inflowFlux[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.internalNodes = set(range(self.mesh.nNodes_global)) - #identify the internal nodes this is ought to be in mesh - ##\todo move this to mesh - for ebNE in range(self.mesh.nExteriorElementBoundaries_global): - ebN = self.mesh.exteriorElementBoundariesArray[ebNE] - eN_global = self.mesh.elementBoundaryElementsArray[ebN,0] - ebN_element = self.mesh.elementBoundaryLocalElementBoundariesArray[ebN,0] - for i in range(self.mesh.nNodes_element): - if i != ebN_element: - I = self.mesh.elementNodesArray[eN_global,i] - self.internalNodes -= set([I]) - self.nNodes_internal = len(self.internalNodes) - self.internalNodesArray=np.zeros((self.nNodes_internal,),'i') - for nI,n in enumerate(self.internalNodes): - self.internalNodesArray[nI]=n - # - del self.internalNodes - self.internalNodes = None - logEvent("Updating local to global mappings",2) - self.updateLocal2Global() - logEvent("Building time integration object",2) - logEvent(memory("inflowBC, internalNodes,updateLocal2Global","OneLevelTransport"),level=4) - #mwf for interpolating subgrid error for gradients etc - if self.stabilization and self.stabilization.usesGradientStabilization: - self.timeIntegration = TimeIntegrationClass(self,integrateInterpolationPoints=True) - else: - self.timeIntegration = TimeIntegrationClass(self) - - if options != None: - self.timeIntegration.setFromOptions(options) - logEvent(memory("TimeIntegration","OneLevelTransport"),level=4) - logEvent("Calculating numerical quadrature formulas",2) - self.calculateQuadrature() - #lay out components/equations contiguously for now - self.offset = [0] - for ci in range(1,self.nc): - self.offset += [self.offset[ci-1]+self.nFreeDOF_global[ci-1]] - self.stride = [1 for ci in range(self.nc)] - #use contiguous layout of components for parallel, requires weak DBC's - # mql. Some ASSERTS to restrict the combination of the methods - if self.coefficients.STABILIZATION_TYPE > 0: - pass - #assert self.timeIntegration.isSSP == True, "If STABILIZATION_TYPE>0, use RKEV timeIntegration within VOF model" - #cond = 'levelNonlinearSolver' in dir(options) and (options.levelNonlinearSolver == - # ExplicitLumpedMassMatrixForRichards or options.levelNonlinearSolver == ExplicitConsistentMassMatrixForRichards) - #assert cond, "If STABILIZATION_TYPE>0, use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards or ExplicitConsistentMassMatrixForRichards" - try: - if 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards: - assert self.coefficients.LUMPED_MASS_MATRIX, "If levelNonlinearSolver=ExplicitLumpedMassMatrix, use LUMPED_MASS_MATRIX=True" - except: - pass - if self.coefficients.LUMPED_MASS_MATRIX == True: - cond = self.coefficients.STABILIZATION_TYPE == 2 - assert cond, "Use lumped mass matrix just with: STABILIZATION_TYPE=2 (smoothness based stab.)" - cond = 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards - assert cond, "Use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards when the mass matrix is lumped" - if self.coefficients.FCT == True: - cond = self.coefficients.STABILIZATION_TYPE > 0, "Use FCT just with STABILIZATION_TYPE>0; i.e., edge based stabilization" - # END OF ASSERTS - - # cek adding empty data member for low order numerical viscosity structures here for now - self.ML = None # lumped mass matrix - self.MC_global = None # consistent mass matrix - self.cterm_global = None - self.cterm_transpose_global = None - # dL_global and dC_global are not the full matrices but just the CSR arrays containing the non zero entries - self.residualComputed=False #TMP - self.dLow= None - self.fluxMatrix = None - self.uDotLow = None - self.uLow = None - self.dt_times_dC_minus_dL = None - self.min_s_bc = None - self.max_s_bc = None - # Aux quantity at DOFs to be filled by optimized code (MQL) - self.quantDOFs = np.zeros(self.u[0].dof.shape, 'd') - self.sLow = np.zeros(self.u[0].dof.shape, 'd') - self.sHigh = np.zeros(self.u[0].dof.shape, 'd') - self.sn = np.zeros(self.u[0].dof.shape, 'd') - comm = Comm.get() - self.comm=comm - if comm.size() > 1: - assert numericalFluxType != None and numericalFluxType.useWeakDirichletConditions,"You must use a numerical flux to apply weak boundary conditions for parallel runs" - self.offset = [0] - for ci in range(1,self.nc): - self.offset += [ci] - self.stride = [self.nc for ci in range(self.nc)] - # - logEvent(memory("stride+offset","OneLevelTransport"),level=4) - - #logEvent("Hi, this is Arnob") - if numericalFluxType != None: - if options is None or options.periodicDirichletConditions is None: - self.numericalFlux = numericalFluxType(self, - dofBoundaryConditionsSetterDict, - advectiveFluxBoundaryConditionsSetterDict, - diffusiveFluxBoundaryConditionsSetterDictDict) - else: - self.numericalFlux = numericalFluxType(self, - dofBoundaryConditionsSetterDict, - advectiveFluxBoundaryConditionsSetterDict, - diffusiveFluxBoundaryConditionsSetterDictDict, - options.periodicDirichletConditions) - else: - self.numericalFlux = None - #set penalty terms - #cek todo move into numerical flux initialization - if 'penalty' in self.ebq_global: - for ebN in range(self.mesh.nElementBoundaries_global): - for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): - self.ebq_global['penalty'][ebN,k] = old_div(self.numericalFlux.penalty_constant,(self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power)) - #penalty term - #cek move to Numerical flux initialization - if 'penalty' in self.ebqe: - for ebNE in range(self.mesh.nExteriorElementBoundaries_global): - ebN = self.mesh.exteriorElementBoundariesArray[ebNE] - for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): - self.ebqe['penalty'][ebNE,k] = old_div(self.numericalFlux.penalty_constant,self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power) - logEvent(memory("numericalFlux","OneLevelTransport"),level=4) - self.elementEffectiveDiametersArray = self.mesh.elementInnerDiametersArray - #use post processing tools to get conservative fluxes, None by default - from proteus import PostProcessingTools - self.velocityPostProcessor = PostProcessingTools.VelocityPostProcessingChooser(self) - logEvent(memory("velocity postprocessor","OneLevelTransport"),level=4) - #helper for writing out data storage - from proteus import Archiver - self.elementQuadratureDictionaryWriter = Archiver.XdmfWriter() - self.elementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() - self.exteriorElementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() - #TODO get rid of this - for ci,fbcObject in list(self.fluxBoundaryConditionsObjectsDict.items()): - self.ebqe[('advectiveFlux_bc_flag',ci)] = np.zeros(self.ebqe[('advectiveFlux_bc',ci)].shape,'i') - for t,g in list(fbcObject.advectiveFluxBoundaryConditionsDict.items()): - if ci in self.coefficients.advection: - self.ebqe[('advectiveFlux_bc',ci)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) - self.ebqe[('advectiveFlux_bc_flag',ci)][t[0],t[1]] = 1 - - if hasattr(self.numericalFlux,'setDirichletValues'): - self.numericalFlux.setDirichletValues(self.ebqe) - if not hasattr(self.numericalFlux,'isDOFBoundary'): - self.numericalFlux.isDOFBoundary = {0:np.zeros(self.ebqe[('u',0)].shape,'i')} - if not hasattr(self.numericalFlux,'ebqe'): - self.numericalFlux.ebqe = {('u',0):np.zeros(self.ebqe[('u',0)].shape,'d')} - #TODO how to handle redistancing calls for calculateCoefficients,calculateElementResidual etc - self.globalResidualDummy = None - compKernelFlag=0 - self.delta_x_ij=None - self.richards = cRichards_base(self.nSpace_global, - self.nQuadraturePoints_element, - self.u[0].femSpace.elementMaps.localFunctionSpace.dim, - self.u[0].femSpace.referenceFiniteElement.localFunctionSpace.dim, - self.testSpace[0].referenceFiniteElement.localFunctionSpace.dim, - self.nElementBoundaryQuadraturePoints_elementBoundary, - compKernelFlag) - if self.movingDomain: - self.MOVING_DOMAIN=1.0 - else: - self.MOVING_DOMAIN=0.0 - #cek hack - self.movingDomain=False - self.MOVING_DOMAIN=0.0 - if self.mesh.nodeVelocityArray is None: - self.mesh.nodeVelocityArray = np.zeros(self.mesh.nodeArray.shape,'d') - self.forceStrongConditions=True - self.dirichletConditionsForceDOF = {} - if self.forceStrongConditions: - for cj in range(self.nc): - self.dirichletConditionsForceDOF[cj] = DOFBoundaryConditions(self.u[cj].femSpace,dofBoundaryConditionsSetterDict[cj],weakDirichletConditions=False) - def FCTStep(self): - import pdb - rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() - limited_solution = np.zeros((len(rowptr) - 1),'d') - #self.u_free_dof_stage_0_l = np.zeros((len(rowptr) - 1),'d') - #self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage], # soln - #fromFreeToGlobal=0 - #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - # self.offset[0], - # self.stride[0], - # self.dirichletConditions[0].global2freeGlobal_global_dofs, - # self.dirichletConditions[0].global2freeGlobal_free_dofs, - # self.u_free_dof_stage_0_l, - # self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage]) - argsDict = cArgumentsDict.ArgumentsDict() - argsDict["bc_mask"] = self.bc_mask - argsDict["NNZ"] = self.nnz - argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs - argsDict["dt"] = self.timeIntegration.dt - argsDict["lumped_mass_matrix"] = self.ML - argsDict["soln"] = self.sn - argsDict["pn"] = self.u[0].dof - argsDict["solH"] = self.sHigh - argsDict["uLow"] = self.sLow - argsDict["uDotLow"] = self.uDotLow - argsDict["limited_solution"] = limited_solution - argsDict["csrRowIndeces_DofLoops"] = rowptr - argsDict["csrColumnOffsets_DofLoops"] = colind - argsDict["MassMatrix"] = MassMatrix - argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL - argsDict["min_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0]) #cek hack just set from physical bounds - argsDict["max_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0] + self.coefficients.thetaSR_types[0]) #cek hack - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - argsDict["MONOLITHIC"] =0#cek hack self.coefficients.MONOLITHIC - #pdb.set_trace() - self.richards.FCTStep(argsDict) - - # self.nnz, # number of non zero entries - # len(rowptr) - 1, # number of DOFs - # self.timeIntegration.dt, - # self.ML, # Lumped mass matrix - # self.sn, - # self.u_dof_old, - # self.sHigh, # high order solution - # self.sLow, - # limited_solution, - # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) - # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) - # MassMatrix, - # self.dt_times_dC_minus_dL, - # self.min_s_bc, - # self.max_s_bc, - # self.coefficients.LUMPED_MASS_MATRIX, - # self.coefficients.MONOLITHIC) - old_dof = self.u[0].dof.copy() - self.invert(limited_solution, self.u[0].dof) - self.timeIntegration.u[:] = self.u[0].dof - #fromFreeToGlobal=1 #direction copying - #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - # self.offset[0], - # self.stride[0], - # self.dirichletConditions[0].global2freeGlobal_global_dofs, - # self.dirichletConditions[0].global2freeGlobal_free_dofs, - # self.u[0].dof, - # limited_solution) - def kth_FCT_step(self): - #import pdb - #pdb.set_trace() - rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() - limitedFlux = np.zeros(self.nnz) - limited_solution = np.zeros((len(rowptr) - 1),'d') - #limited_solution[:] = self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage] - fromFreeToGlobal=0 #direction copying - cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - self.offset[0], - self.stride[0], - self.dirichletConditions[0].global2freeGlobal_global_dofs, - self.dirichletConditions[0].global2freeGlobal_free_dofs, - limited_solution, - self.timeintegration.u_dof_stage[0][self.timeIntegration.lstage]) - - self.richards.kth_FCT_step( - self.timeIntegration.dt, - self.coefficients.num_fct_iter, - self.nnz, # number of non zero entries - len(rowptr) - 1, # number of DOFs - MassMatrix, - self.ML, # Lumped mass matrix - self.u_dof_old, - limited_solution, - self.uDotLow, - self.uLow, - self.dLow, - self.fluxMatrix, - limitedFlux, - rowptr, - colind) - - self.timeIntegration.u[:] = limited_solution - #self.u[0].dof[:] = limited_solution - fromFreeToGlobal=1 #direction copying - cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - self.offset[0], - self.stride[0], - self.dirichletConditions[0].global2freeGlobal_global_dofs, - self.dirichletConditions[0].global2freeGlobal_free_dofs, - self.u[0].dof, - limited_solution) - def calculateCoefficients(self): - pass - def calculateElementResidual(self): - if self.globalResidualDummy != None: - self.getResidual(self.u[0].dof,self.globalResidualDummy) - def getResidual(self,u,r): - import pdb - import copy - """ - Calculate the element residuals and add in to the global residual - """ - cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, - self.jacobian) - if self.u_dof_old is None: - # Pass initial condition to u_dof_old - self.u_dof_old = np.copy(self.u[0].dof) - rowptr, colind, nzval = self.jacobian.getCSRrepresentation() - nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix - r.fill(0.0) - ######################## - ### COMPUTE C MATRIX ### - ######################## - if self.cterm_global is None: - # since we only need cterm_global to persist, we can drop the other self.'s - self.cterm = {} - self.cterm_a = {} - self.cterm_global = {} - self.cterm_transpose = {} - self.cterm_a_transpose = {} - self.cterm_global_transpose = {} - rowptr, colind, nzval = self.jacobian.getCSRrepresentation() - nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix - di = self.q[('grad(u)', 0)].copy() # direction of derivative - # JACOBIANS (FOR ELEMENT TRANSFORMATION) - self.q[('J')] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nSpace_global, - self.nSpace_global), - 'd') - self.q[('inverse(J)')] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nSpace_global, - self.nSpace_global), - 'd') - self.q[('det(J)')] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element), - 'd') - self.u[0].femSpace.elementMaps.getJacobianValues(self.elementQuadraturePoints, - self.q['J'], - self.q['inverse(J)'], - self.q['det(J)']) - self.q['abs(det(J))'] = np.abs(self.q['det(J)']) - # SHAPE FUNCTIONS - self.q[('w', 0)] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nDOF_test_element[0]), - 'd') - self.q[('w*dV_m', 0)] = self.q[('w', 0)].copy() - self.u[0].femSpace.getBasisValues(self.elementQuadraturePoints, self.q[('w', 0)]) - cfemIntegrals.calculateWeightedShape(self.elementQuadratureWeights[('u', 0)], - self.q['abs(det(J))'], - self.q[('w', 0)], - self.q[('w*dV_m', 0)]) - # GRADIENT OF TEST FUNCTIONS - self.q[('grad(w)', 0)] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nDOF_test_element[0], - self.nSpace_global), - 'd') - self.u[0].femSpace.getBasisGradientValues(self.elementQuadraturePoints, - self.q['inverse(J)'], - self.q[('grad(w)', 0)]) - self.q[('grad(w)*dV_f', 0)] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nDOF_test_element[0], - self.nSpace_global), - 'd') - cfemIntegrals.calculateWeightedShapeGradients(self.elementQuadratureWeights[('u', 0)], - self.q['abs(det(J))'], - self.q[('grad(w)', 0)], - self.q[('grad(w)*dV_f', 0)]) - ########################## - ### LUMPED MASS MATRIX ### - ########################## - # assume a linear mass term - dm = np.ones(self.q[('u', 0)].shape, 'd') - elementMassMatrix = np.zeros((self.mesh.nElements_global, - self.nDOF_test_element[0], - self.nDOF_trial_element[0]), 'd') - cfemIntegrals.updateMassJacobian_weak_lowmem(dm, - self.q[('w', 0)], - self.q[('w*dV_m', 0)], - elementMassMatrix) - self.MC_a = nzval.copy() - self.MC_global = SparseMat(self.nFreeDOF_global[0], - self.nFreeDOF_global[0], - nnz, - self.MC_a, - colind, - rowptr) - cfemIntegrals.zeroJacobian_CSR(self.nnz, self.MC_global) - cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.csrRowIndeces[(0, 0)], - self.csrColumnOffsets[(0, 0)], - elementMassMatrix, - self.MC_global) - self.ML = np.zeros((self.nFreeDOF_global[0],), 'd') - for i in range(self.nFreeDOF_global[0]): - self.ML[i] = self.MC_a[rowptr[i]:rowptr[i + 1]].sum() - np.testing.assert_almost_equal(self.ML.sum(), - self.mesh.volume, - err_msg="Trace of lumped mass matrix should be the domain volume", verbose=True) - for d in range(self.nSpace_global): # spatial dimensions - # C matrices - self.cterm[d] = np.zeros((self.mesh.nElements_global, - self.nDOF_test_element[0], - self.nDOF_trial_element[0]), 'd') - self.cterm_a[d] = nzval.copy() - #self.cterm_a[d] = np.zeros(nzval.size) - self.cterm_global[d] = SparseMat(self.nFreeDOF_global[0], - self.nFreeDOF_global[0], - nnz, - self.cterm_a[d], - colind, - rowptr) - cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global[d]) - di[:] = 0.0 - di[..., d] = 1.0 - cfemIntegrals.updateHamiltonianJacobian_weak_lowmem(di, - self.q[('grad(w)*dV_f', 0)], - self.q[('w', 0)], - self.cterm[d]) # int[(di*grad(wj))*wi*dV] - cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.csrRowIndeces[(0, 0)], - self.csrColumnOffsets[(0, 0)], - self.cterm[d], - self.cterm_global[d]) - # C Transpose matrices - self.cterm_transpose[d] = np.zeros((self.mesh.nElements_global, - self.nDOF_test_element[0], - self.nDOF_trial_element[0]), 'd') - self.cterm_a_transpose[d] = nzval.copy() - self.cterm_global_transpose[d] = SparseMat(self.nFreeDOF_global[0], - self.nFreeDOF_global[0], - nnz, - self.cterm_a_transpose[d], - colind, - rowptr) - cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global_transpose[d]) - di[:] = 0.0 - di[..., d] = -1.0 - cfemIntegrals.updateAdvectionJacobian_weak_lowmem(di, - self.q[('w', 0)], - self.q[('grad(w)*dV_f', 0)], - self.cterm_transpose[d]) # -int[(-di*grad(wi))*wj*dV] - cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.csrRowIndeces[(0, 0)], - self.csrColumnOffsets[(0, 0)], - self.cterm_transpose[d], - self.cterm_global_transpose[d]) - - rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() - else: - Cy = np.zeros(Cx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() - else: - Cz = np.zeros(Cx.shape, 'd') - rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() - else: - CTy = np.zeros(CTx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() - else: - CTz = np.zeros(CTx.shape, 'd') - - # This is dummy. I just care about the csr structure of the sparse matrix - self.dLow = np.zeros(Cx.shape, 'd') - self.fluxMatrix = np.zeros(Cx.shape, 'd') - self.dt_times_dC_minus_dL = np.zeros(Cx.shape, 'd') - nFree = len(rowptr)-1 - self.min_s_bc = np.zeros(nFree, 'd') + 1E10 - self.max_s_bc = np.zeros(nFree, 'd') - 1E10 - self.uDotLow = np.zeros(nFree, 'd') - self.uLow = np.zeros(nFree, 'd') - # - # cek end computationa of cterm_global - # - # cek showing mquezada an example of using cterm_global sparse matrix - # calculation y = c*x where x==1 - # direction=0 - #rowptr, colind, c = self.cterm_global[direction].getCSRrepresentation() - #y = np.zeros((self.nFreeDOF_global[0],),'d') - #x = np.ones((self.nFreeDOF_global[0],),'d') - # ij=0 - # for i in range(self.nFreeDOF_global[0]): - # for offset in range(rowptr[i],rowptr[i+1]): - # j = colind[offset] - # y[i] += c[ij]*x[j] - # ij+=1 - #Load the unknowns into the finite element dof - self.timeIntegration.calculateCoefs() - self.timeIntegration.calculateU(u) - self.setUnknowns(self.timeIntegration.u) - #cek can put in logic to skip of BC's don't depend on t or u - #Dirichlet boundary conditions - self.numericalFlux.setDirichletValues(self.ebqe) - #flux boundary conditions - #cek hack, just using advective flux for flux BC for now - for t,g in list(self.fluxBoundaryConditionsObjectsDict[0].advectiveFluxBoundaryConditionsDict.items()): - self.ebqe[('advectiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) - self.ebqe[('advectiveFlux_bc_flag',0)][t[0],t[1]] = 1 - # for t,g in self.fluxBoundaryConditionsObjectsDict[0].diffusiveFluxBoundaryConditionsDict.iteritems(): - # self.ebqe[('diffusiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) - # self.ebqe[('diffusiveFlux_bc_flag',0)][t[0],t[1]] = 1 - #self.shockCapturing.lag=True - if self.forceStrongConditions: - self.bc_mask = np.ones_like(self.u[0].dof) - for cj in range(len(self.dirichletConditionsForceDOF)): - for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): - self.u[cj].dof[dofN] = g(self.dirichletConditionsForceDOF[cj].DOFBoundaryPointDict[dofN],self.timeIntegration.t) - self.u_dof_old[dofN] = self.u[cj].dof[dofN] - self.bc_mask[dofN] = 0.0 - degree_polynomial = 1 - try: - degree_polynomial = self.u[0].femSpace.order - except: - pass - - argsDict = cArgumentsDict.ArgumentsDict() - argsDict["bc_mask"] = self.bc_mask - argsDict["dt"] = self.timeIntegration.dt - argsDict["Theta"] = 1.0 - argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi - argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi - argsDict["mesh_dof"] = self.mesh.nodeArray - argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray - argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN - argsDict["mesh_l2g"] = self.mesh.elementNodesArray - argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] - argsDict["u_trial_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi - argsDict["u_test_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi - argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace - argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace - argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] - argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals - argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians - argsDict["nElements_global"] = self.mesh.nElements_global - argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] - argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, - argsDict["isSeepageFace"] = self.coefficients.isSeepageFace - argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] - argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] - argsDict["rho"] = self.coefficients.rho - argsDict["beta"] = self.coefficients.beta - argsDict["gravity"] = self.coefficients.gravity - argsDict["alpha"] = self.coefficients.vgm_alpha_types - argsDict["n"] = self.coefficients.vgm_n_types - argsDict["thetaR"] = self.coefficients.thetaR_types - argsDict["thetaSR"] = self.coefficients.thetaSR_types - argsDict["KWs"] = self.coefficients.Ksw_types - argsDict["useMetrics"] = 0.0 - argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf - argsDict["lag_shockCapturing"] = 0 - argsDict["shockCapturingDiffusion"] = 0.0 - argsDict["sc_uref"] = 0.0 - argsDict["sc_alpha"] = 0.0 - argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g - argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] - argsDict["elementDiameter"] = self.mesh.elementDiametersArray - argsDict["degree_polynomial"] = degree_polynomial - argsDict["u_dof"] = self.u[0].dof - argsDict["u_dof_old"] = self.u_dof_old - argsDict["velocity"] = self.q['velocity'] - argsDict["q_m"] = self.timeIntegration.m_tmp[0] - argsDict["q_u"] = self.q[('u',0)] - argsDict["q_dV"] = self.q[('dV_u',0)] - argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] - argsDict["cfl"] = self.q[('cfl',0)] - argsDict["q_numDiff_u"] = self.q[('cfl',0)] - argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] - argsDict["offset_u"] = self.offset[0] - argsDict["stride_u"] = self.stride[0] - argsDict["globalResidual"] = r - argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global - argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray - argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray - argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray - argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] - argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] - argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] - argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] - argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] - argsDict["ebqe_phi"] = self.ebqe[('u',0)] - argsDict["epsFact"] = 0.0 - argsDict["ebqe_u"] = self.ebqe[('u',0)] - argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] - argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE - # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION - argsDict["cE"] = self.coefficients.cE - argsDict["cK"] = self.coefficients.cK - # PARAMETERS FOR LOG BASED ENTROPY FUNCTION - argsDict["uL"] = self.coefficients.uL - argsDict["uR"] = self.coefficients.uR - # PARAMETERS FOR EDGE VISCOSITY - argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs - argsDict["NNZ"] = self.nnz - argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern - argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) - argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) - argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms - argsDict["globalJacobian"] = self.jacobian.getCSRrepresentation()[2] - # C matrices - argsDict["Cx"] = Cx - argsDict["Cy"] = Cy - argsDict["Cz"] = Cz - argsDict["CTx"] = CTx - argsDict["CTy"] = CTy - argsDict["CTz"] = CTz - argsDict["ML"] = self.ML - argsDict["delta_x_ij"] = self.delta_x_ij - # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE - argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE - # FLUX CORRECTED TRANSPORT - argsDict["dLow"] = self.dLow - argsDict["fluxMatrix"] = self.fluxMatrix - argsDict["uDotLow"] = self.uDotLow - argsDict["uLow"] = self.uLow - argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL - argsDict["min_s_bc"] = self.min_s_bc - argsDict["max_s_bc"] = self.max_s_bc - argsDict["quantDOFs"] = self.quantDOFs - argsDict["sLow"] = self.sLow - argsDict["sn"] = self.sn - - argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - #print(anb_seepage_flux) - #argsDict["anb_seepage_flux_n"] = self.coefficients.anb_seepage_flux_n - - #print("Seepage Flux from Python file", self.coefficients.anb_seepage_flux) - - - if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG - self.calculateResidual = self.richards.calculateResidual - self.calculateJacobian = self.richards.calculateJacobian - else: - self.calculateResidual = self.richards.calculateResidual_entropy_viscosity - self.calculateJacobian = self.richards.calculateMassMatrix - if self.delta_x_ij is None: - self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') - self.calculateResidual(argsDict) - #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] - #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf - #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] - #self.timeIntegration.calculateElementCoefficients(self.q) - if self.forceStrongConditions:# - for cj in range(len(self.dirichletConditionsForceDOF)):# - for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): - r[self.offset[cj]+self.stride[cj]*dofN] = 0 - if self.stabilization: - self.stabilization.accumulateSubgridMassHistory(self.q) - logEvent("Global residual",level=9,data=r) - self.nonlinear_function_evaluations += 1 - if self.globalResidualDummy is None: - self.globalResidualDummy = np.zeros(r.shape,'d') - - #print("Hello from the python file", self.coefficients.anb_seepage_flux) - #logEvent("Hello from the python file", self.coefficients.anb_seepage_flux") - - - - - def invert(self,u,r): - #u=s - #r=p - import pdb - import copy - """ - Calculate the element residuals and add in to the global residual - """ - self.sHigh[:] = u - rowptr, colind, nzval = self.jacobian.getCSRrepresentation() - nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix - r.fill(0.0) - rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() - else: - Cy = np.zeros(Cx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() - else: - Cz = np.zeros(Cx.shape, 'd') - rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() - else: - CTy = np.zeros(CTx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() - else: - CTz = np.zeros(CTx.shape, 'd') - - # This is dummy. I just care about the csr structure of the sparse matrix - nFree = len(rowptr)-1 - degree_polynomial = 1 - try: - degree_polynomial = self.u[0].femSpace.order - except: - pass - if self.delta_x_ij is None: - self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') - argsDict = cArgumentsDict.ArgumentsDict() - argsDict["dt"] = self.timeIntegration.dt - argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi - argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi - argsDict["mesh_dof"] = self.mesh.nodeArray - argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray - argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN - argsDict["mesh_l2g"] = self.mesh.elementNodesArray - argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] - argsDict["u_trial_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi - argsDict["u_test_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi - argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace - argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace - argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] - argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals - argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians - argsDict["nElements_global"] = self.mesh.nElements_global - argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] - argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, - argsDict["isSeepageFace"] = self.coefficients.isSeepageFace - argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] - argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] - argsDict["rho"] = self.coefficients.rho - argsDict["beta"] = self.coefficients.beta - argsDict["gravity"] = self.coefficients.gravity - argsDict["alpha"] = self.coefficients.vgm_alpha_types - argsDict["n"] = self.coefficients.vgm_n_types - argsDict["thetaR"] = self.coefficients.thetaR_types - argsDict["thetaSR"] = self.coefficients.thetaSR_types - argsDict["KWs"] = self.coefficients.Ksw_types - argsDict["useMetrics"] = 0.0 - argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf - argsDict["lag_shockCapturing"] = 0 - argsDict["shockCapturingDiffusion"] = 0.0 - argsDict["sc_uref"] = 0.0 - argsDict["sc_alpha"] = 0.0 - argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g - argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] - argsDict["elementDiameter"] = self.mesh.elementDiametersArray - argsDict["degree_polynomial"] = degree_polynomial - argsDict["u_dof"] = u#self.u[0].dof - argsDict["u_dof_old"] = self.u[0].dof - argsDict["velocity"] = self.q['velocity'] - argsDict["q_m"] = self.timeIntegration.m_tmp[0] - argsDict["q_u"] = self.q[('u',0)] - argsDict["q_dV"] = self.q[('dV_u',0)] - argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] - argsDict["cfl"] = self.q[('cfl',0)] - argsDict["q_numDiff_u"] = self.q[('cfl',0)] - argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] - argsDict["offset_u"] = self.offset[0] - argsDict["stride_u"] = self.stride[0] - argsDict["globalResidual"] = r - argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global - argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray - argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray - argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray - argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] - argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] - argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] - argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] - argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] - argsDict["ebqe_phi"] = self.ebqe[('u',0)] - argsDict["epsFact"] = 0.0 - argsDict["ebqe_u"] = self.ebqe[('u',0)] - argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] - argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE - # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION - argsDict["cE"] = self.coefficients.cE - argsDict["cK"] = self.coefficients.cK - # PARAMETERS FOR LOG BASED ENTROPY FUNCTION - argsDict["uL"] = self.coefficients.uL - argsDict["uR"] = self.coefficients.uR - # PARAMETERS FOR EDGE VISCOSITY - argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs - argsDict["NNZ"] = self.nnz - argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern - argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) - argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) - argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms - # C matrices - argsDict["Cx"] = Cx - argsDict["Cy"] = Cy - argsDict["Cz"] = Cz - argsDict["CTx"] = CTx - argsDict["CTy"] = CTy - argsDict["CTz"] = CTz - argsDict["ML"] = self.ML - argsDict["delta_x_ij"] = self.delta_x_ij - # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE - argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE - # FLUX CORRECTED TRANSPORT - argsDict["dLow"] = self.dLow - argsDict["fluxMatrix"] = self.fluxMatrix - argsDict["uDotLow"] = self.uDotLow - argsDict["uLow"] = self.uLow - argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL - argsDict["min_s_bc"] = self.min_s_bc - argsDict["max_s_bc"] = self.max_s_bc - argsDict["quantDOFs"] = self.quantDOFs - argsDict["sLow"] = self.sLow - argsDict["sn"] = self.sn - #Arnob trying to print flux - argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - #print("Hi",anb_seepage_flux) - #print("Hi Seepage Flux", self.coefficients.anb_seepage_flux) - - self.richards.invert(argsDict) - # self.timeIntegration.dt, - # self.u[0].femSpace.elementMaps.psi, - # self.u[0].femSpace.elementMaps.grad_psi, - # self.mesh.nodeArray, - # self.mesh.nodeVelocityArray, - # self.MOVING_DOMAIN, - # self.mesh.elementNodesArray, - # self.elementQuadratureWeights[('u',0)], - # self.u[0].femSpace.psi, - # self.u[0].femSpace.grad_psi, - # self.u[0].femSpace.psi, - # self.u[0].femSpace.grad_psi, - # #element boundary - # self.u[0].femSpace.elementMaps.psi_trace, - # self.u[0].femSpace.elementMaps.grad_psi_trace, - # self.elementBoundaryQuadratureWeights[('u',0)], - # self.u[0].femSpace.psi_trace, - # self.u[0].femSpace.grad_psi_trace, - # self.u[0].femSpace.psi_trace, - # self.u[0].femSpace.grad_psi_trace, - # self.u[0].femSpace.elementMaps.boundaryNormals, - # self.u[0].femSpace.elementMaps.boundaryJacobians, - # #physics - # self.mesh.nElements_global, - # self.ebqe['penalty'],#double* ebqe_penalty_ext, - # self.mesh.elementMaterialTypes,#int* elementMaterialTypes, - # self.coefficients.isSeepageFace, - # self.coefficients.sdInfo[(0,0)][0],#int* a_rowptr, - # self.coefficients.sdInfo[(0,0)][1],#int* a_colind, - # self.coefficients.rho,#double rho, - # self.coefficients.beta,#double beta, - # self.coefficients.gravity,#double* gravity, - # self.coefficients.vgm_alpha_types,#double* alpha, - # self.coefficients.vgm_n_types,#double* n, - # self.coefficients.thetaR_types,#double* thetaR, - # self.coefficients.thetaSR_types,#double* thetaSR, - # self.coefficients.Ksw_types,#double* KWs, - # False,#self.coefficients.useMetrics, - # self.timeIntegration.alpha_bdf, - # 0,#self.shockCapturing.lag, - # 0.0,#cek hack self.shockCapturing.shockCapturingFactor, - # 0.0,#self.coefficients.sc_uref, - # 0.0,#self.coefficients.sc_beta, - # self.u[0].femSpace.dofMap.l2g, - # self.l2g[0]['freeGlobal'], - # self.mesh.elementDiametersArray, - # degree_polynomial, - # self.sHigh, - # self.u_dof_old, - # self.q['velocity'],#self.coefficients.q_v, - # self.timeIntegration.m_tmp[0], - # self.q[('u',0)], - # self.timeIntegration.beta_bdf[0], - # self.q[('cfl',0)], - # self.edge_based_cfl, - # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff[0], - # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff_last[0], - # self.offset[0],self.stride[0], - # r, - # self.mesh.nExteriorElementBoundaries_global, - # self.mesh.exteriorElementBoundariesArray, - # self.mesh.elementBoundaryElementsArray, - # self.mesh.elementBoundaryLocalElementBoundariesArray, - # self.ebqe['velocity'],#self.coefficients.ebqe_v, - # self.numericalFlux.isDOFBoundary[0], - # self.numericalFlux.ebqe[('u',0)], - # self.ebqe[('advectiveFlux_bc_flag',0)], - # self.ebqe[('advectiveFlux_bc',0)], - # self.ebqe[('u',0)],#cek hack self.coefficients.ebqe_phi, - # 0.0,#cek hack self.coefficients.epsFact, - # self.ebqe[('u',0)], - # self.ebqe[('advectiveFlux',0)], - # # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION - # self.coefficients.cE, - # self.coefficients.cK, - # # PARAMETERS FOR LOG BASED ENTROPY FUNCTION - # self.coefficients.uL, - # self.coefficients.uR, - # # PARAMETERS FOR EDGE VISCOSITY - # len(rowptr) - 1, # num of DOFs - # len(Cx), # num of non-zero entries in the sparsity pattern - # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) - # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) - # self.csrRowIndeces[(0, 0)], # row indices (convenient for element loops) - # self.csrColumnOffsets[(0, 0)], # column indices (convenient for element loops) - # self.csrColumnOffsets_eb[(0, 0)], # indices for boundary terms - # # C matrices - # Cx, - # Cy, - # Cz, - # CTx, - # CTy, - # CTz, - # self.ML, - # self.delta_x_ij, - # # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - # self.coefficients.LUMPED_MASS_MATRIX, - # self.coefficients.STABILIZATION_TYPE, - # self.coefficients.ENTROPY_TYPE, - # # FLUX CORRECTED TRANSPORT - # self.dLow, - # self.fluxMatrix, - # self.uDotLow, - # self.uLow, - # self.dt_times_dC_minus_dL, - # self.min_s_bc, - # self.max_s_bc, - # self.quantDOFs) - #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] - #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf - #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] - #self.timeIntegration.calculateElementCoefficients(self.q) - #if self.forceStrongConditions:# - # for cj in range(len(self.dirichletConditionsForceDOF)):# - # for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): - # r[self.offset[cj]+self.stride[cj]*dofN] = 0 - #if self.stabilization: - # self.stabilization.accumulateSubgridMassHistory(self.q) - #logEvent("Global residual",level=9,data=r) - #self.nonlinear_function_evaluations += 1 - #if self.globalResidualDummy is None: - # self.globalResidualDummy = numpy.zeros(r.shape,'d') - def postStep(self, t, firstStep=False): - with open('seepage_flux_nnnn', "a") as f: - f.write("\n Time"+ ",\t" +"Seepage\n") - f.write(repr(t)+ ",\t" +repr(self.coefficients.anb_seepage_flux)) - def getJacobian(self,jacobian): - if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG - cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, - jacobian) - degree_polynomial = 1 - try: - degree_polynomial = self.u[0].femSpace.order - except: - pass - if self.delta_x_ij is None: - self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') - argsDict = cArgumentsDict.ArgumentsDict() - argsDict["dt"] = self.timeIntegration.dt - argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi - argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi - argsDict["mesh_dof"] = self.mesh.nodeArray - argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray - argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN - argsDict["mesh_l2g"] = self.mesh.elementNodesArray - argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] - argsDict["u_trial_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi - argsDict["u_test_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi - argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace - argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace - argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] - argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals - argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians - argsDict["nElements_global"] = self.mesh.nElements_global - argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] - argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, - argsDict["isSeepageFace"] = self.coefficients.isSeepageFace - argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] - argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] - argsDict["rho"] = self.coefficients.rho - argsDict["beta"] = self.coefficients.beta - argsDict["gravity"] = self.coefficients.gravity - argsDict["alpha"] = self.coefficients.vgm_alpha_types - argsDict["n"] = self.coefficients.vgm_n_types - argsDict["thetaR"] = self.coefficients.thetaR_types - argsDict["thetaSR"] = self.coefficients.thetaSR_types - argsDict["KWs"] = self.coefficients.Ksw_types - argsDict["useMetrics"] = 0.0 - argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf - argsDict["lag_shockCapturing"] = 0 - argsDict["shockCapturingDiffusion"] = 0.0 - argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g - argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] - argsDict["elementDiameter"] = self.mesh.elementDiametersArray - argsDict["degree_polynomial"] = degree_polynomial - argsDict["u_dof"] = self.u[0].dof - argsDict["velocity"] = self.q['velocity'] - argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] - argsDict["cfl"] = self.q[('cfl',0)] - argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] - argsDict["csrRowIndeces_u_u"] = self.csrRowIndeces[(0,0)] - argsDict["csrColumnOffsets_u_u"] = self.csrColumnOffsets[(0,0)] - argsDict["globalJacobian"] = jacobian.getCSRrepresentation()[2] - argsDict["delta_x_ij"] = self.delta_x_ij - argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global - argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray - argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray - argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray - argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] - argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] - argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] - argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] - argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] - argsDict["csrColumnOffsets_eb_u_u"] = self.csrColumnOffsets_eb[(0,0)] - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - - #arnob trying to calculate flux - #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - #Arnob trying to print flux - #argsDict["anb_seepage_flux"] = self.calculateResidual.anb_seepage_flux - - #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - #print("Hi Seepage Flux", self.coefficients.anb_seepage_flux) - #print("Hi Seepage Flux",anb_seepage_flux) - #print("The seepage is ", anb_seepage_flux) - - - - - self.calculateJacobian(argsDict) - if self.forceStrongConditions: - for dofN in list(self.dirichletConditionsForceDOF[0].DOFBoundaryConditionsDict.keys()): - global_dofN = self.offset[0]+self.stride[0]*dofN - self.nzval[np.where(self.colind == global_dofN)] = 0.0 #column - self.nzval[self.rowptr[global_dofN]:self.rowptr[global_dofN+1]] = 0.0 #row - zeroRow=True - for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]):#row - if (self.colind[i] == global_dofN): - self.nzval[i] = 1.0 - zeroRow = False - if zeroRow: - raise RuntimeError("Jacobian has a zero row because sparse matrix has no diagonal entry at row "+repr(global_dofN)+". You probably need add diagonal mass or reaction term") - #scaling = 1.0#probably want to add some scaling to match non-dirichlet diagonals in linear system - #for cj in range(self.nc): - # for dofN in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.keys()): - # global_dofN = self.offset[cj]+self.stride[cj]*dofN - # for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]): - # if (self.colind[i] == global_dofN): - # self.nzval[i] = scaling - # else: - # self.nzval[i] = 0.0 - logEvent("Jacobian ",level=10,data=jacobian) - #mwf decide if this is reasonable for solver statistics - self.nonlinear_function_jacobian_evaluations += 1 - return jacobian - def calculateElementQuadrature(self): - """ - Calculate the physical location and weights of the quadrature rules - and the shape information at the quadrature points. - - This function should be called only when the mesh changes. - """ - #self.u[0].femSpace.elementMaps.getValues(self.elementQuadraturePoints, - # self.q['x']) - self.u[0].femSpace.elementMaps.getBasisValuesRef(self.elementQuadraturePoints) - self.u[0].femSpace.elementMaps.getBasisGradientValuesRef(self.elementQuadraturePoints) - self.u[0].femSpace.getBasisValuesRef(self.elementQuadraturePoints) - self.u[0].femSpace.getBasisGradientValuesRef(self.elementQuadraturePoints) - self.coefficients.initializeElementQuadrature(self.timeIntegration.t,self.q) - if self.stabilization != None: - self.stabilization.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) - self.stabilization.initializeTimeIntegration(self.timeIntegration) - if self.shockCapturing != None: - self.shockCapturing.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) - def calculateElementBoundaryQuadrature(self): - pass - def calculateExteriorElementBoundaryQuadrature(self): - """ - Calculate the physical location and weights of the quadrature rules - and the shape information at the quadrature points on global element boundaries. - - This function should be called only when the mesh changes. - """ - # - #get physical locations of element boundary quadrature points - # - #assume all components live on the same mesh - self.u[0].femSpace.elementMaps.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.elementMaps.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.elementMaps.getValuesGlobalExteriorTrace(self.elementBoundaryQuadraturePoints, - self.ebqe['x']) - self.fluxBoundaryConditionsObjectsDict = dict([(cj,FluxBoundaryConditions(self.mesh, - self.nElementBoundaryQuadraturePoints_elementBoundary, - self.ebqe[('x')], - getAdvectiveFluxBoundaryConditions=self.advectiveFluxBoundaryConditionsSetterDict[cj], - getDiffusiveFluxBoundaryConditions=self.diffusiveFluxBoundaryConditionsSetterDictDict[cj])) - for cj in list(self.advectiveFluxBoundaryConditionsSetterDict.keys())]) - self.coefficients.initializeGlobalExteriorElementBoundaryQuadrature(self.timeIntegration.t,self.ebqe) - #argsDict = cArgumentsDict.ArgumentsDict() - #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - #print("Hi", self.coefficients.anb_seepage_flux) - - #print("The seepage is ", anb_seepage_flux) - def estimate_mt(self): - pass - def calculateSolutionAtQuadrature(self): - pass - def calculateAuxiliaryQuantitiesAfterStep(self): - pass - def postStep(self, t, firstStep=False): - with open('seepage_flux_nnnnk', "a") as f: - f.write("\n Time"+ ",\t" +"Seepage\n") - f.write(repr(t)+ ",\t" +repr(self.coefficients.anb_seepage_flux)) - - - -#argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux -#anb_seepage_flux= self.coefficients.anb_seepage_flux -#print("Hi",anb_seepage_flux) - - -#print("Hello from the python file", self.coefficients.anb_seepage_flux) diff --git a/richards_fct/richards/edit/__init__.py b/richards_fct/richards/edit/__init__.py deleted file mode 100755 index c45e66de51..0000000000 --- a/richards_fct/richards/edit/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -""" -Modules for simulating variably saturated single-phase flow -""" - -__all__ = ["Richards", - "cRichards"] diff --git a/richards_fct/richards/edit/cRichards.cpp b/richards_fct/richards/edit/cRichards.cpp deleted file mode 100755 index 21c500c55c..0000000000 --- a/richards_fct/richards/edit/cRichards.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "pybind11/pybind11.h" -#include "pybind11/stl_bind.h" - -#define FORCE_IMPORT_ARRAY -#include "Richards.h" - -#if defined(__GNUC__) && !defined(__clang__) - namespace workaround - { - inline void define_allocators() - { - std::allocator a0; - std::allocator a1; - } - } -#endif - - -namespace py = pybind11; -using proteus::Richards_base; -PYBIND11_MODULE(cRichards, m) -{ - xt::import_numpy(); - - py::class_(m, "cRichards_base") - .def(py::init(&proteus::newRichards)) - .def("calculateResidual", &Richards_base::calculateResidual) - .def("calculateJacobian", &Richards_base::calculateJacobian) - .def("invert", &Richards_base::invert) - .def("FCTStep", &Richards_base::FCTStep) - .def("kth_FCT_step", &Richards_base::kth_FCT_step) - .def("calculateResidual_entropy_viscosity", &Richards_base::calculateResidual_entropy_viscosity) - .def("calculateMassMatrix", &Richards_base::calculateMassMatrix); -} - - diff --git a/richards_fct/richards/new_update/Richards.h b/richards_fct/richards/new_update/Richards.h deleted file mode 100644 index d9e6a76a4a..0000000000 --- a/richards_fct/richards/new_update/Richards.h +++ /dev/null @@ -1,2966 +0,0 @@ -#ifndef Richards_H -#define Richards_H -#include -#include -#include -#include "CompKernel.h" -#include "ModelFactory.h" -#include "../mprans/ArgumentsDict.h" -#include "xtensor-python/pyarray.hpp" -#define nnz nSpace - -namespace py = pybind11; -#define POWER_SMOOTHNESS_INDICATOR 2 -#define IS_BETAij_ONE 0 -#define GLOBAL_FCT 0 -namespace proteus -{ - // Power entropy // - inline double ENTROPY(const double& phi, const double& phiL, const double& phiR){ - return 1./2.*std::pow(fabs(phi),2.); - } - inline double DENTROPY(const double& phi, const double& phiL, const double& phiR){ - return fabs(phi)*(phi>=0 ? 1 : -1); - } - // Log entropy // for level set from 0 to 1 - inline double ENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ - return std::log(fabs((phi-phiL)*(phiR-phi))+1E-14); - } - inline double DENTROPY_LOG(const double& phi, const double& phiL, const double& phiR){ - return (phiL+phiR-2*phi)*((phi-phiL)*(phiR-phi)>=0 ? 1 : -1)/(fabs((phi-phiL)*(phiR-phi))+1E-14); - } -} - -namespace proteus -{ - class Richards_base - { - //The base class defining the interface - public: - virtual ~Richards_base(){} - virtual void calculateResidual(arguments_dict& args)=0; - virtual void calculateJacobian(arguments_dict& args)=0; - virtual void invert(arguments_dict& args)=0; - virtual void FCTStep(arguments_dict& args)=0; - virtual void kth_FCT_step(arguments_dict& args)=0; - virtual void calculateResidual_entropy_viscosity(arguments_dict& args)=0; - virtual void calculateMassMatrix(arguments_dict& args)=0; - }; - - template - class Richards : public Richards_base - { - public: - const int nDOF_test_X_trial_element; - CompKernelType ck; - Richards(): - nDOF_test_X_trial_element(nDOF_test_element*nDOF_trial_element), - ck() - {} - inline - void evaluateCoefficients(const int rowptr[nSpace], - const int colind[nnz], - const double rho, - const double beta, - const double gravity[nSpace], - const double alpha, - const double n_vg, - const double thetaR, - const double thetaSR, - const double KWs[nnz], - const double& u, - double& m, - double& dm, - double f[nSpace], - double df[nSpace], - double a[nnz], - double da[nnz], - double as[nnz], - double& kr, - double& dkr) - { - const int nSpace2 = nSpace * nSpace; - double psiC; - double pcBar; - double pcBar_n; - double pcBar_nM1; - double pcBar_nM2; - double onePlus_pcBar_n; - double sBar; - double sqrt_sBar; - double DsBar_DpsiC; - double thetaW; - double DthetaW_DpsiC; - double vBar; - double vBar2; - double DvBar_DpsiC; - double KWr; - double DKWr_DpsiC; - double rho2 = rho * rho; - double thetaS; - double rhom; - double drhom; - double m_vg; - double pcBarStar; - double sqrt_sBarStar; - - psiC = -u; - m_vg = 1.0 - 1.0 / n_vg; - thetaS = thetaR + thetaSR; - if (psiC > 0.0) - { - pcBar = alpha * psiC; - pcBarStar = pcBar; - if (pcBar < 1.0e-8) - pcBarStar = 1.0e-8; - pcBar_nM2 = pow(pcBarStar, n_vg - 2); - pcBar_nM1 = pcBar_nM2 * pcBar; - pcBar_n = pcBar_nM1 * pcBar; - onePlus_pcBar_n = 1.0 + pcBar_n; - - sBar = pow(onePlus_pcBar_n, -m_vg); - /* using -mn = 1-n */ - DsBar_DpsiC = alpha * (1.0 - n_vg) * (sBar/onePlus_pcBar_n)*pcBar_nM1; - - vBar = 1.0-pcBar_nM1*sBar; - vBar2 = vBar*vBar; - DvBar_DpsiC = -alpha*(n_vg-1.0)*pcBar_nM2*sBar - pcBar_nM1*DsBar_DpsiC; - - thetaW = thetaSR*sBar + thetaR; - DthetaW_DpsiC = thetaSR * DsBar_DpsiC; - - sqrt_sBar = sqrt(sBar); - sqrt_sBarStar = sqrt_sBar; - if (sqrt_sBar < 1.0e-8) - sqrt_sBarStar = 1.0e-8; - KWr= sqrt_sBar*vBar2; - DKWr_DpsiC= ((0.5/sqrt_sBarStar)*DsBar_DpsiC*vBar2 - + - 2.0*sqrt_sBar*vBar*DvBar_DpsiC); - } - else - { - thetaW = thetaS; - DthetaW_DpsiC = 0.0; - KWr = 1.0; - DKWr_DpsiC = 0.0; - } - //slight compressibility - rhom = rho*exp(beta*u); - drhom = beta*rhom; - m = rhom*thetaW; - dm = -rhom*DthetaW_DpsiC+drhom*thetaW; - for (int I=0;I thetaS || thetaW <= thetaR) - { - //cek debug - std::cout<<"rho "< 0.0) - { - isDOFBoundary = 1; - bc_u = bc_u_seepage; - } - else - { - isDOFBoundary = 0; - flux = 0.0; - } - } - /* //set DOF flag and flux correctly if seepage face */ - /* if (isSeepageFace) */ - /* { */ - /* if (flux < 0.0 || u < bc_u_seepage) */ - /* { */ - /* isDOFBoundary = 0; */ - /* flux = 0.0; */ - /* } */ - /* else */ - /* { */ - /* isDOFBoundary = 1; */ - /* bc_u = bc_u_seepage; */ - /* } */ - /* } */ - /* //Dirichlet penalty */ - /* if (isDOFBoundary) */ - /* flux += penalty*(u-bc_u); */ - } - else - flux = bc_flux; - } - - void exteriorNumericalFluxJacobian(const int rowptr[nSpace], - const int colind[nnz], - const int isDOFBoundary, - const double n[nSpace], - const double K[nnz], - const double dK[nnz], - const double grad_psi[nSpace], - const double grad_v[nSpace], - const double dK_rho_g[nSpace], - const double v, - const double penalty, - double& fluxJacobian) - { - if (isDOFBoundary) - { - fluxJacobian = 0.0; - for(int I=0;I& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - double sc_uref = args.scalar("sc_uref"); - double sc_alpha = args.scalar("sc_alpha"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& u_dof_old = args.array("u_dof_old"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m = args.array("q_m"); - xt::pyarray& q_u = args.array("q_u"); - xt::pyarray& q_dV = args.array("q_dV"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - int offset_u = args.scalar("offset_u"); - int stride_u = args.scalar("stride_u"); - xt::pyarray& globalResidual = args.array("globalResidual"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& ebqe_phi = args.array("ebqe_phi"); - double epsFact = args.scalar("epsFact"); - xt::pyarray& ebqe_u = args.array("ebqe_u"); - xt::pyarray& ebqe_flux = args.array("ebqe_flux"); - // PARAMETERS FOR EDGE BASED STABILIZATION - double cE = args.scalar("cE"); - double cK = args.scalar("cK"); - // PARAMETERS FOR LOG BASED ENTROPY FUNCTION - double uL = args.scalar("uL"); - double uR = args.scalar("uR"); - // PARAMETERS FOR EDGE VISCOSITY - int numDOFs = args.scalar("numDOFs"); - int NNZ = args.scalar("NNZ"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); - xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); - xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); - xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); - // C matrices - xt::pyarray& Cx = args.array("Cx"); - xt::pyarray& Cy = args.array("Cy"); - xt::pyarray& Cz = args.array("Cz"); - xt::pyarray& CTx = args.array("CTx"); - xt::pyarray& CTy = args.array("CTy"); - xt::pyarray& CTz = args.array("CTz"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); - int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); - // FOR FCT - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& fluxMatrix = args.array("fluxMatrix"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); - xt::pyarray& min_s_bc = args.array("min_s_bc"); - xt::pyarray& max_s_bc = args.array("max_s_bc"); - // AUX QUANTITIES OF INTEREST - xt::pyarray& quantDOFs = args.array("quantDOFs"); - xt::pyarray& sLow = args.array("sLow"); - xt::pyarray& sn = args.array("sn"); - - assert(a_rowptr.data()[nSpace] == nnz); - assert(a_rowptr.data()[nSpace] == nSpace); - //cek should this be read in? - double Ct_sge = 4.0; - - //loop over elements to compute volume integrals and load them into element and global residual - // - //eN is the element index - //eN_k is the quadrature point index for a scalar - //eN_k_nSpace is the quadrature point index for a vector - //eN_i is the element test function index - //eN_j is the element trial function index - //eN_k_j is the quadrature point index for a trial function - //eN_k_i is the quadrature point index for a trial function - for(int eN=0;eN& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); - xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); - xt::pyarray& globalJacobian = args.array("globalJacobian"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - assert(a_rowptr.data()[nSpace] == nnz); - assert(a_rowptr.data()[nSpace] == nSpace); - double Ct_sge = 4.0; - - // - //loop over elements to compute volume integrals and load them into the element Jacobians and global Jacobian - // - for(int eN=0;eN& bc_mask = args.array("bc_mask"); - int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern - int numDOFs = args.scalar("numDOFs"); //number of DOFs - double dt = args.scalar("dt"); - xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) - xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn - xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn - xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& limited_solution = args.array("limited_solution"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets - xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices - xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 - xt::pyarray& max_s_bc = args.array("max_s_bc"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int MONOLITHIC = args.scalar("MONOLITHIC"); - register double Rpos[numDOFs], Rneg[numDOFs]; - register double FluxCorrectionMatrix[NNZ]; - register double solL[numDOFs]; - register double sdot[numDOFs]; - ////////////////// - // LOOP in DOFs // - ////////////////// - int ij=0; - for (int i=0; i 0) ? 1. : 0.); - Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); - - //update ij - ij+=1; - //std::cout<<"sdoti error"<0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])) - * FluxCorrectionMatrix[ij]; - alpha_dot = fmin(1.0, beta_ij*fabs(alpha_fA)/MassMatrix.data()[ij]/fmax(1.0e-8,fabs(sdoti-sdotj))); - if (MONOLITHIC == 0) - { - ith_Limiter_times_FluxCorrectionMatrix += alpha_fA; - } - else - { - ith_Limiter_times_FluxCorrectionMatrix += alpha_fA + (LUMPED_MASS_MATRIX == 1 ? 0. : 1.)*dt*alpha_dot*MassMatrix.data()[ij]*(sdoti-sdotj); - } - //update ij - ij+=1; - } - limited_solution.data()[i] = solL[i] + 1./lumped_mass_matrix.data()[i]*ith_Limiter_times_FluxCorrectionMatrix*bc_mask[i]; - } - } - - void kth_FCT_step(arguments_dict& args) - { - int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern - int numDOFs = args.scalar("numDOFs"); //number of DOFs - int num_fct_iter = args.scalar("num_fct_iter"); - double dt = args.scalar("dt"); - xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) - xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn - xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn - xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& solLim = args.array("limited_solution"); - xt::pyarray& MC = args.array("MC"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& FluxMatrix = args.array("FluxMatrix"); - xt::pyarray& limitedFlux = args.array("limited_Flux"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets - xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices - xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 - xt::pyarray& max_s_bc = args.array("max_s_bc"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int MONOLITHIC = args.scalar("MONOLITHIC"); - register double Rpos[numDOFs], Rneg[numDOFs]; - int ij=0; - - ////////////////////////////////////////////////////// - // ********** COMPUTE LOW ORDER SOLUTION ********** // - ////////////////////////////////////////////////////// - if (num_fct_iter == 0) - { // No FCT for global bounds - for (int i=0; i 0) ? 1. : 0.); - // update ij - ij+=1; - } - // compute Q vectors - double mi = ML.data()[i]; - double solLimi = solLim.data()[i]; - double Qposi = mi*(maxi-solLimi); - // compute R vectors - Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - } - ij=0; - for (int i=0; i0 ? Rposi : Rpos[j]); - // compute limited flux - ith_Limiter_times_FluxCorrectionMatrix += Lij*Fluxij; - - // update limited flux - limitedFlux.data()[ij] = Lij*Fluxij; - - //update FluxMatrix - FluxMatrix.data()[ij] = Fluxij; - - //update ij - ij+=1; - } - //update limited solution - double mi = ML.data()[i]; - solLim.data()[i] += 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; - } - } - } - - // ***************************************** // - // ********** HIGH ORDER SOLUTION ********** // - // ***************************************** // - ij=0; - for (int i=0; i 0 ? 1. : 0.); - Pnegi += fij * (fij < 0 ? 1. : 0.); - //update ij - ij+=1; - } - // compute Q vectors // - double mi = ML.data()[i]; - double Qposi = mi*(maxi-solLim.data()[i]); - double Qnegi = mi*(mini-solLim.data()[i]); - // compute R vectors // - Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); - } - - // COMPUTE LIMITERS // - ij=0; - for (int i=0; i 0 ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j]); - // compute ith_limited_flux_correction - ith_limited_flux_correction += Lij*fij; - ij+=1; - } - double mi = ML.data()[i]; - solLim[i] += 1./mi*ith_limited_flux_correction; - } - } - - void calculateResidual_entropy_viscosity(arguments_dict& args) - { - xt::pyarray& globalJacobian = args.array("globalJacobian"); - double Theta = args.scalar("Theta"); - xt::pyarray& bc_mask = args.array("bc_mask"); - double dt = args.scalar("dt"); - xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - int nElements_global = args.scalar("nElements_global"); - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - double sc_uref = args.scalar("sc_uref"); - double sc_alpha = args.scalar("sc_alpha"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& r_l2g = args.array("r_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - int degree_polynomial = args.scalar("degree_polynomial"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& u_dof_old = args.array("u_dof_old"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m = args.array("q_m"); - xt::pyarray& q_u = args.array("q_u"); - xt::pyarray& q_dV = args.array("q_dV"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u = args.array("q_numDiff_u"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - int offset_u = args.scalar("offset_u"); - int stride_u = args.scalar("stride_u"); - xt::pyarray& globalResidual = args.array("globalResidual"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& ebqe_phi = args.array("ebqe_phi"); - double epsFact = args.scalar("epsFact"); - xt::pyarray& ebqe_u = args.array("ebqe_u"); - xt::pyarray& ebqe_flux = args.array("ebqe_flux"); - // PARAMETERS FOR EDGE BASED STABILIZATION - double cE = args.scalar("cE"); - double cK = args.scalar("cK"); - // PARAMETERS FOR LOG BASED ENTROPY FUNCTION - double uL = args.scalar("uL"); - double uR = args.scalar("uR"); - // PARAMETERS FOR EDGE VISCOSITY - int numDOFs = args.scalar("numDOFs"); - int NNZ = args.scalar("NNZ"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); - xt::pyarray& csrRowIndeces_CellLoops = args.array("csrRowIndeces_CellLoops"); - xt::pyarray& csrColumnOffsets_CellLoops = args.array("csrColumnOffsets_CellLoops"); - xt::pyarray& csrColumnOffsets_eb_CellLoops = args.array("csrColumnOffsets_eb_CellLoops"); - // C matrices - xt::pyarray& Cx = args.array("Cx"); - xt::pyarray& Cy = args.array("Cy"); - xt::pyarray& Cz = args.array("Cz"); - xt::pyarray& CTx = args.array("CTx"); - xt::pyarray& CTy = args.array("CTy"); - xt::pyarray& CTz = args.array("CTz"); - xt::pyarray& ML = args.array("ML"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - // PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - int STABILIZATION_TYPE = args.scalar("STABILIZATION_TYPE"); - int ENTROPY_TYPE = args.scalar("ENTROPY_TYPE"); - // FOR FCT - xt::pyarray& dLow = args.array("dLow"); - xt::pyarray& fluxMatrix = args.array("fluxMatrix"); - xt::pyarray& uDotLow = args.array("uDotLow"); - xt::pyarray& uLow = args.array("uLow"); - xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); - xt::pyarray& min_s_bc = args.array("min_s_bc"); - xt::pyarray& max_s_bc = args.array("max_s_bc"); - // AUX QUANTITIES OF INTEREST - xt::pyarray& quantDOFs = args.array("quantDOFs"); - xt::pyarray& sLow = args.array("sLow"); - xt::pyarray& sn = args.array("sn"); - register double Rpos[numDOFs], Rneg[numDOFs]; - //register double FluxCorrectionMatrix[NNZ]; - // NOTE: This function follows a different (but equivalent) implementation of the smoothness based indicator than NCLS.h - // Allocate space for the transport matrices - // This is used for first order KUZMIN'S METHOD - register double TransportMatrix[NNZ],TransportMatrixConsistent[NNZ]; - register double TransportMatrixn[NNZ],TransportMatrixConsistentn[NNZ]; - std::valarray u_free_dof(numDOFs); - std::valarray u_free_dof_old(numDOFs); - std::valarray ML2(numDOFs); - for(int eN=0;eN= 0 && isFluxBoundary_u[ebNE_kb] != 1 ) //outflow. This is handled via the transport matrices. Then flux_ext=0 and dflux_ext!=0 */ - /* { */ - /* dflux_ext = flow; */ - /* flux_ext = 0; */ - /* // save external u */ - /* ebqe_u[ebNE_kb] = u_ext; */ - /* } */ - /* else // inflow. This is handled via the boundary integral. Then flux_ext!=0 and dflux_ext=0 */ - /* { */ - /* dflux_ext = 0; */ - /* // save external u */ - /* ebqe_u[ebNE_kb] = isDOFBoundary_u[ebNE_kb]*ebqe_bc_u_ext[ebNE_kb]+(1-isDOFBoundary_u[ebNE_kb])*u_ext; */ - /* if (isDOFBoundary_u[ebNE_kb] == 1) */ - /* flux_ext = ebqe_bc_u_ext[ebNE_kb]*flow; */ - /* else if (isFluxBoundary_u[ebNE_kb] == 1) */ - /* flux_ext = ebqe_bc_flux_u_ext[ebNE_kb]; */ - /* else */ - /* { */ - /* std::cout<<"warning: VOF open boundary with no external trace, setting to zero for inflow"<= 0.) - { - alpha_numerator_pos += alpha_num; - alpha_denominator_pos += alpha_num; - } - else - { - alpha_numerator_neg += alpha_num; - alpha_denominator_neg += fabs(alpha_num); - } - //update ij - ij+=1; - } - // scale g vector by lumped mass matrix - if (fabs(ML.data()[i] - ML2[i]) > 1.0e-16) - std::cout<<"ML "< 0.0) - // assert( (xi[I] - xj[I]) == delta_x_ij[offset*3+I]); - //gi_times_x += gi[I]*(xi[I]-xj[I]); - gi_times_x += gi[I]*delta_x_ij.data()[offset*3+I]; - } - // compute the positive and negative part of gi*(xi-xj) - SumPos += gi_times_x > 0 ? gi_times_x : 0; - SumNeg += gi_times_x < 0 ? gi_times_x : 0; - } - double sigmaPosi = fmin(1.,(fabs(SumNeg)+1E-15)/(SumPos+1E-15)); - double sigmaNegi = fmin(1.,(SumPos+1E-15)/(fabs(SumNeg)+1E-15)); - double alpha_numi = fabs(sigmaPosi*alpha_numerator_pos + sigmaNegi*alpha_numerator_neg); - double alpha_deni = sigmaPosi*alpha_denominator_pos + sigmaNegi*alpha_denominator_neg; - if (IS_BETAij_ONE == 1) - { - alpha_numi = fabs(alpha_numerator_pos + alpha_numerator_neg); - alpha_deni = alpha_denominator_pos + alpha_denominator_neg; - } - double alphai = alpha_numi/(alpha_deni+1E-15); - quantDOFs.data()[i] = alphai; - - if (POWER_SMOOTHNESS_INDICATOR==0) - psi[i] = 1.0; - else - psi[i] = std::pow(alphai,POWER_SMOOTHNESS_INDICATOR); //NOTE: they use alpha^2 in the paper - } - ///////////////////////////////////////////// - // ** LOOP IN DOFs FOR EDGE BASED TERMS ** // - ///////////////////////////////////////////// - ij=0; - for (int i=0; i Dissipation matrices as well. - double soli = u_free_dof[i]; // solution at time tn for the ith DOF - double solni = u_free_dof_old[i]; // solution at time tn for the ith DOF - for (int I=0;I mMax) - { - std::cout<<"mass out of bounds "< 0) ? 1. : 0.); - // Pnegi += FluxCorrectionMatrix[ij]*((FluxCorrectionMatrix[ij] < 0) ? 1. : 0.); - // ij+=1; - // } - // double mi = ML[i]; - // double solni = u_dof_old[i]; - // double Qposi = mi*(maxi-solni); - // double Qnegi = mi*(mini-solni); - - //std::cout << Qposi << std::endl; - // Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - // Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); - - //if (Rpos[i] < 0) - //{ - // std::cout << mi << "\t" << maxi << "\t" << solni << std::endl; - // std::cout << Qposi << "\t" << Pposi << std::endl; - // std::cout << Rpos[i] << std::endl; - //abort(); - //} - //} - - //ij=0; - //for (int i=0; i 1.0 || Rposi < 0.0) - //std::cout << "Rposi: " << Rposi << std::endl; - //if (Rnegi > 1.0 || Rnegi < 0.0) - //std::cout << "Rnegi: " << Rnegi << std::endl; - - // LOOP OVER THE SPARSITY PATTERN (j-LOOP)// - // for (int offset=csrRowIndeces_DofLoops.data()[i]; - // offset0) ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j])); - // //Lij=0.0; - // ith_Limiter_times_FluxCorrectionMatrix += Lij*FluxCorrectionMatrix[ij]; - // //update ij - // ij+=1; - // } - // double mi = ML[i]; - // double solni = u_dof_old[i]; - // globalResidual[i] = solni + 1.0/mi*ith_Limiter_times_FluxCorrectionMatrix; - //} - - } - - void invert(arguments_dict& args) - { - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - xt::pyarray& globalResidual = args.array("globalResidual"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - int numDOFs = args.scalar("numDOFs"); - for (int i=0; i mMax) - { - std::cout<<"mass out of bounds "<("dt"); - xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); - xt::pyarray& mesh_grad_trial_ref = args.array("mesh_grad_trial_ref"); - xt::pyarray& mesh_dof = args.array("mesh_dof"); - xt::pyarray& mesh_velocity_dof = args.array("mesh_velocity_dof"); - double MOVING_DOMAIN = args.scalar("MOVING_DOMAIN"); - xt::pyarray& mesh_l2g = args.array("mesh_l2g"); - xt::pyarray& dV_ref = args.array("dV_ref"); - xt::pyarray& u_trial_ref = args.array("u_trial_ref"); - xt::pyarray& u_grad_trial_ref = args.array("u_grad_trial_ref"); - xt::pyarray& u_test_ref = args.array("u_test_ref"); - xt::pyarray& u_grad_test_ref = args.array("u_grad_test_ref"); - //element boundary - xt::pyarray& mesh_trial_trace_ref = args.array("mesh_trial_trace_ref"); - xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); - xt::pyarray& dS_ref = args.array("dS_ref"); - xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); - xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); - xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); - xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); - xt::pyarray& normal_ref = args.array("normal_ref"); - xt::pyarray& boundaryJac_ref = args.array("boundaryJac_ref"); - //physics - int nElements_global = args.scalar("nElements_global"); - //new - xt::pyarray& ebqe_penalty_ext = args.array("ebqe_penalty_ext"); - xt::pyarray& elementMaterialTypes = args.array("elementMaterialTypes"); - xt::pyarray& isSeepageFace = args.array("isSeepageFace"); - xt::pyarray& a_rowptr = args.array("a_rowptr"); - xt::pyarray& a_colind = args.array("a_colind"); - double rho = args.scalar("rho"); - double beta = args.scalar("beta"); - xt::pyarray& gravity = args.array("gravity"); - xt::pyarray& alpha = args.array("alpha"); - xt::pyarray& n = args.array("n"); - xt::pyarray& thetaR = args.array("thetaR"); - xt::pyarray& thetaSR = args.array("thetaSR"); - xt::pyarray& KWs = args.array("KWs"); - //end new - double useMetrics = args.scalar("useMetrics"); - double alphaBDF = args.scalar("alphaBDF"); - int lag_shockCapturing = args.scalar("lag_shockCapturing"); - double shockCapturingDiffusion = args.scalar("shockCapturingDiffusion"); - xt::pyarray& u_l2g = args.array("u_l2g"); - xt::pyarray& r_l2g = args.array("r_l2g"); - xt::pyarray& elementDiameter = args.array("elementDiameter"); - int degree_polynomial = args.scalar("degree_polynomial"); - xt::pyarray& u_dof = args.array("u_dof"); - xt::pyarray& velocity = args.array("velocity"); - xt::pyarray& q_m_betaBDF = args.array("q_m_betaBDF"); - xt::pyarray& cfl = args.array("cfl"); - xt::pyarray& q_numDiff_u_last = args.array("q_numDiff_u_last"); - xt::pyarray& csrRowIndeces_u_u = args.array("csrRowIndeces_u_u"); - xt::pyarray& csrColumnOffsets_u_u = args.array("csrColumnOffsets_u_u"); - xt::pyarray& globalJacobian = args.array("globalJacobian"); - xt::pyarray& delta_x_ij = args.array("delta_x_ij"); - int nExteriorElementBoundaries_global = args.scalar("nExteriorElementBoundaries_global"); - xt::pyarray& exteriorElementBoundariesArray = args.array("exteriorElementBoundariesArray"); - xt::pyarray& elementBoundaryElementsArray = args.array("elementBoundaryElementsArray"); - xt::pyarray& elementBoundaryLocalElementBoundariesArray = args.array("elementBoundaryLocalElementBoundariesArray"); - xt::pyarray& ebqe_velocity_ext = args.array("ebqe_velocity_ext"); - xt::pyarray& isDOFBoundary_u = args.array("isDOFBoundary_u"); - xt::pyarray& ebqe_bc_u_ext = args.array("ebqe_bc_u_ext"); - xt::pyarray& isFluxBoundary_u = args.array("isFluxBoundary_u"); - xt::pyarray& ebqe_bc_flux_ext = args.array("ebqe_bc_flux_ext"); - xt::pyarray& csrColumnOffsets_eb_u_u = args.array("csrColumnOffsets_eb_u_u"); - int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - //std::cout<<"ndjaco address "<(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - else if (nSpaceIn == 2) - return proteus::chooseAndAllocateDiscretization2D(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - else - { - assert(nSpaceIn == 3); - return proteus::chooseAndAllocateDiscretization(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, - CompKernelFlag); - } - } -}//proteus -#endif diff --git a/richards_fct/richards/new_update/Richards.py b/richards_fct/richards/new_update/Richards.py deleted file mode 100644 index 841fcd0884..0000000000 --- a/richards_fct/richards/new_update/Richards.py +++ /dev/null @@ -1,1745 +0,0 @@ -from __future__ import division -from builtins import range -from past.utils import old_div -import proteus -from .cRichards import * -import numpy as np -from proteus.Transport import OneLevelTransport -from proteus.Transport import TC_base, NonlinearEquation, logEvent, memory -from proteus.Transport import FluxBoundaryConditions, Comm, cfemIntegrals -from proteus.Transport import DOFBoundaryConditions, Quadrature -from proteus.mprans import cArgumentsDict -from proteus.LinearAlgebraTools import SparseMat -from proteus import TimeIntegration -from proteus.NonlinearSolvers import ExplicitLumpedMassMatrixForRichards - -class ThetaScheme(TimeIntegration.BackwardEuler): - def __init__(self,transport,integrateInterpolationPoints=False): - self.transport=transport - TimeIntegration.BackwardEuler.__init__(self,transport, integrateInterpolationPoints) - def updateTimeHistory(self,resetFromDOF=False): - TimeIntegration.BackwardEuler.updateTimeHistory(self,resetFromDOF) - self.transport.u_dof_old[:] = self.u -class RKEV(TimeIntegration.SSP): - from proteus import TimeIntegration - """ - Wrapper for SSPRK time integration using EV - - ... more to come ... - """ - - def __init__(self, transport, timeOrder=1, runCFL=0.1, integrateInterpolationPoints=False): - TimeIntegration.SSP.__init__(self, transport, integrateInterpolationPoints=integrateInterpolationPoints) - self.runCFL = runCFL - self.dtLast = None - self.isAdaptive = True - # About the cfl - assert transport.coefficients.STABILIZATION_TYPE > 0, "SSP method just works for edge based EV methods; i.e., STABILIZATION_TYPE>0" - assert hasattr(transport, 'edge_based_cfl'), "No edge based cfl defined" - self.cfl = transport.edge_based_cfl - # Stuff particular for SSP - self.timeOrder = timeOrder # order of approximation - self.nStages = timeOrder # number of stages total - self.lstage = 0 # last stage completed - # storage vectors - self.u_dof_last = {} - # per component stage values, list with array at each stage - self.u_dof_stage = {} - for ci in range(self.nc): - if ('m', ci) in transport.q: - self.u_dof_last[ci] = transport.u[ci].dof.copy() - self.u_dof_stage[ci] = [] - for k in range(self.nStages + 1): - self.u_dof_stage[ci].append(transport.u[ci].dof.copy()) - - # def set_dt(self, DTSET): - # self.dt = DTSET # don't update t - def choose_dt(self): - comm = Comm.get() - maxCFL = 1.0e-6 - maxCFL = max(maxCFL, comm.globalMax(self.cfl.max())) - self.dt = old_div(self.runCFL, maxCFL) - if self.dtLast is None: - self.dtLast = self.dt - self.t = self.tLast + self.dt - self.substeps = [self.t for i in range(self.nStages)] # Manuel is ignoring different time step levels for now - - def initialize_dt(self, t0, tOut, q): - """ - Modify self.dt - """ - self.tLast = t0 - self.choose_dt() - self.t = t0 + self.dt - - def setCoefficients(self): - """ - beta are all 1's here - mwf not used right now - """ - self.alpha = np.zeros((self.nStages, self.nStages), 'd') - self.dcoefs = np.zeros((self.nStages), 'd') - - def updateStage(self): - """ - Need to switch to use coefficients - """ - self.lstage += 1 - assert self.timeOrder in [1, 2, 3] - assert self.lstage > 0 and self.lstage <= self.timeOrder - if self.timeOrder == 3: - if self.lstage == 1: - logEvent("First stage of SSP33 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - # update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] - elif self.lstage == 2: - logEvent("Second stage of SSP33 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - self.u_dof_stage[ci][self.lstage] *= old_div(1., 4.) - self.u_dof_stage[ci][self.lstage] += 3. / 4. * self.u_dof_last[ci] - # Update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_stage[ci][self.lstage] - elif self.lstage == 3: - logEvent("Third stage of SSP33 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - self.u_dof_stage[ci][self.lstage] *= old_div(2.0, 3.0) - self.u_dof_stage[ci][self.lstage] += 1.0 / 3.0 * self.u_dof_last[ci] - # update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_last[ci] - # update solution to u[0].dof - self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] - elif self.timeOrder == 2: - if self.lstage == 1: - logEvent("First stage of SSP22 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - # Update u_dof_old - self.transport.u_dof_old[:] = self.transport.u[ci].dof - elif self.lstage == 2: - logEvent("Second stage of SSP22 method", level=4) - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof - self.u_dof_stage[ci][self.lstage][:] *= old_div(1., 2.) - self.u_dof_stage[ci][self.lstage][:] += 1. / 2. * self.u_dof_last[ci] - # update u_dof_old - self.transport.u_dof_old[:] = self.u_dof_last[ci] - # update solution to u[0].dof - self.transport.u[ci].dof[:] = self.u_dof_stage[ci][self.lstage] - else: - assert self.timeOrder == 1 - for ci in range(self.nc): - self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof[:] - self.transport.u_dof_old[:] = self.transport.u[ci].dof - - def initializeTimeHistory(self, resetFromDOF=True): - """ - Push necessary information into time history arrays - """ - for ci in range(self.nc): - self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] - for k in range(self.nStages): - self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] - - def updateTimeHistory(self, resetFromDOF=False): - """ - assumes successful step has been taken - """ - - self.t = self.tLast + self.dt - for ci in range(self.nc): - self.u_dof_last[ci][:] = self.transport.u[ci].dof[:] - for k in range(self.nStages): - self.u_dof_stage[ci][k][:] = self.transport.u[ci].dof[:] - self.lstage = 0 - self.dtLast = self.dt - self.tLast = self.t - - def generateSubsteps(self, tList): - """ - create list of substeps over time values given in tList. These correspond to stages - """ - self.substeps = [] - tLast = self.tLast - for t in tList: - dttmp = t - tLast - self.substeps.extend([tLast + dttmp for i in range(self.nStages)]) - tLast = t - - def resetOrder(self, order): - """ - initialize data structures for stage updges - """ - self.timeOrder = order # order of approximation - self.nStages = order # number of stages total - self.lstage = 0 # last stage completed - # storage vectors - # per component stage values, list with array at each stage - self.u_dof_stage = {} - for ci in range(self.nc): - if ('m', ci) in self.transport.q: - self.u_dof_stage[ci] = [] - for k in range(self.nStages + 1): - self.u_dof_stage[ci].append(self.transport.u[ci].dof.copy()) - self.substeps = [self.t for i in range(self.nStages)] - - def setFromOptions(self, nOptions): - """ - allow classes to set various numerical parameters - """ - if 'runCFL' in dir(nOptions): - self.runCFL = nOptions.runCFL - flags = ['timeOrder'] - for flag in flags: - if flag in dir(nOptions): - val = getattr(nOptions, flag) - setattr(self, flag, val) - if flag == 'timeOrder': - self.resetOrder(self.timeOrder) - -class Coefficients(proteus.TransportCoefficients.TC_base): - """ - version of Re where element material type id's used in evals - """ - from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2 - from proteus.ctransportCoefficients import conservativeHeadRichardsMualemVanGenuchten_sd_het - def __init__(self, - nd, - Ksw_types, - vgm_n_types, - vgm_alpha_types, - thetaR_types, - thetaSR_types, - gravity, - density, - beta, - diagonal_conductivity=True, - getSeepageFace=None, - # FOR EDGE BASED EV - STABILIZATION_TYPE=0, - ENTROPY_TYPE=2, # logarithmic - LUMPED_MASS_MATRIX=False, - MONOLITHIC=True, - FCT=False, - forceStrongBoundaryConditions=False, - num_fct_iter=1, - # FOR ENTROPY VISCOSITY - cE=1.0, - uL=0.0, - uR=1.0, - # FOR ARTIFICIAL COMPRESSION - cK=1.0, - # OUTPUT quantDOFs - outputQuantDOFs=False): - variableNames=['pressure_head'] - nc=1 - mass={0:{0:'nonlinear'}} - advection={0:{0:'nonlinear'}} - diffusion={0:{0:{0:'nonlinear'}}} - potential={0:{0:'u'}} - reaction={0:{0:'linear'}} - hamiltonian={} - self.getSeepageFace=getSeepageFace - self.gravity=gravity - self.rho = density - self.beta=beta - self.vgm_n_types = vgm_n_types - self.vgm_alpha_types = vgm_alpha_types - self.thetaR_types = thetaR_types - self.thetaSR_types = thetaSR_types - self.elementMaterialTypes = None - self.exteriorElementBoundaryTypes = None - self.materialTypes_q = None - self.materialTypes_ebq = None - self.materialTypes_ebqe = None - self.nd = nd - self.nMaterialTypes = len(thetaR_types) - self.q = {}; self.ebqe = {}; self.ebq = {}; self.ebq_global={} - #try to allow some flexibility in input of permeability/conductivity tensor - self.diagonal_conductivity = diagonal_conductivity - self.Ksw_types_in = Ksw_types - if self.diagonal_conductivity: - sparseDiffusionTensors = {(0,0):(np.arange(self.nd+1,dtype='i'), - np.arange(self.nd,dtype='i'))} - - assert len(Ksw_types.shape) in [1,2], "if diagonal conductivity true then Ksw_types scalar or vector of diagonal entries" - #allow scalar input Ks - if len(Ksw_types.shape)==1: - self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd),'d') - for I in range(self.nd): - self.Ksw_types[:,I] = Ksw_types - else: - self.Ksw_types = Ksw_types - else: #full - sparseDiffusionTensors = {(0,0):(np.arange(self.nd**2+1,step=self.nd,dtype='i'), - np.array([list(range(self.nd)) for row in range(self.nd)],dtype='i'))} - assert len(Ksw_types.shape) in [1,2], "if full tensor conductivity true then Ksw_types scalar or 'flattened' row-major representation of entries" - if len(Ksw_types.shape)==1: - self.Ksw_types = np.zeros((self.nMaterialTypes,self.nd**2),'d') - for I in range(self.nd): - self.Ksw_types[:,I*self.nd+I] = Ksw_types - else: - assert Ksw_types.shape[1] == self.nd**2 - self.Ksw_types = Ksw_types - # EDGE BASED (AND ENTROPY) VISCOSITY - self.LUMPED_MASS_MATRIX = LUMPED_MASS_MATRIX - self.MONOLITHIC = MONOLITHIC - self.STABILIZATION_TYPE = STABILIZATION_TYPE - self.ENTROPY_TYPE = ENTROPY_TYPE - self.FCT = FCT - self.num_fct_iter=num_fct_iter - self.uL = uL - self.uR = uR - self.cK = cK - self.forceStrongConditions = forceStrongBoundaryConditions - self.cE = cE - self.outputQuantDOFs = outputQuantDOFs - TC_base.__init__(self, - nc, - mass, - advection, - diffusion, - potential, - reaction, - hamiltonian, - variableNames, - sparseDiffusionTensors = sparseDiffusionTensors, - useSparseDiffusion = True) - - def initializeMesh(self,mesh): - from proteus.SubsurfaceTransportCoefficients import BlockHeterogeneousCoefficients - self.elementMaterialTypes,self.exteriorElementBoundaryTypes,self.elementBoundaryTypes = BlockHeterogeneousCoefficients(mesh).initializeMaterialTypes() - #want element boundary material types for evaluating heterogeneity - #not boundary conditions - self.isSeepageFace = np.zeros((mesh.nExteriorElementBoundaries_global),'i') - if self.getSeepageFace != None: - for ebNE in range(mesh.nExteriorElementBoundaries_global): - #mwf missing ebNE-->ebN? - ebN = mesh.exteriorElementBoundariesArray[ebNE] - #print "eb flag",mesh.elementBoundaryMaterialTypes[ebN] - #print self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) - self.isSeepageFace[ebNE] = self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) - #print self.isSeepageFace - def initializeElementQuadrature(self,t,cq): - self.materialTypes_q = self.elementMaterialTypes - self.q_shape = cq[('u',0)].shape -# cq['Ks'] = np.zeros(self.q_shape,'d') -# for k in range(self.q_shape[1]): -# cq['Ks'][:,k] = self.Ksw_types[self.elementMaterialTypes,0] - self.q[('vol_frac',0)] = np.zeros(self.q_shape,'d') - def initializeElementBoundaryQuadrature(self,t,cebq,cebq_global): - self.materialTypes_ebq = np.zeros(cebq[('u',0)].shape[0:2],'i') - self.ebq_shape = cebq[('u',0)].shape - for ebN_local in range(self.ebq_shape[1]): - self.materialTypes_ebq[:,ebN_local] = self.elementMaterialTypes - self.ebq[('vol_frac',0)] = np.zeros(self.ebq_shape,'d') - - def initializeGlobalExteriorElementBoundaryQuadrature(self,t,cebqe): - self.materialTypes_ebqe = self.exteriorElementBoundaryTypes - self.ebqe_shape = cebqe[('u',0)].shape - self.ebqe[('vol_frac',0)] = np.zeros(self.ebqe_shape,'d') - # - def evaluate(self,t,c): - if c[('u',0)].shape == self.q_shape: - materialTypes = self.materialTypes_q - vol_frac = self.q[('vol_frac',0)] - elif c[('u',0)].shape == self.ebqe_shape: - materialTypes = self.materialTypes_ebqe - vol_frac = self.ebqe[('vol_frac',0)] - elif c[('u',0)].shape == self.ebq_shape: - materialTypes = self.materialTypes_ebq - vol_frac = self.ebq[('vol_frac',0)] - else: - assert False, "no materialType found to match c[('u',0)].shape= %s " % c[('u',0)].shape - self.conservativeHeadRichardsMualemVanGenuchten_sd_het(self.sdInfo[(0,0)][0], - self.sdInfo[(0,0)][1], - materialTypes, - self.rho, - self.beta, - self.gravity, - self.vgm_alpha_types, - self.vgm_n_types, - self.thetaR_types, - self.thetaSR_types, - self.Ksw_types, - c[('u',0)], - c[('m',0)], - c[('dm',0,0)], - c[('f',0)], - c[('df',0,0)], - c[('a',0,0)], - c[('da',0,0,0)], - vol_frac) - # print "Picard---------------------------------------------------------------" - # c[('df',0,0)][:] = 0.0 - # c[('da',0,0,0)][:] = 0.0 -# self.conservativeHeadRichardsMualemVanGenuchtenHetEvaluateV2(materialTypes, -# self.rho, -# self.beta, -# self.gravity, -# self.vgm_alpha_types, -# self.vgm_n_types, -# self.thetaR_types, -# self.thetaSR_types, -# self.Ksw_types, -# c[('u',0)], -# c[('m',0)], -# c[('dm',0,0)], -# c[('f',0)], -# c[('df',0,0)], -# c[('a',0,0)], -# c[('da',0,0,0)]) - #mwf debug - if (np.isnan(c[('da',0,0,0)]).any() or - np.isnan(c[('a',0,0)]).any() or - np.isnan(c[('df',0,0)]).any() or - np.isnan(c[('f',0)]).any() or - np.isnan(c[('u',0)]).any() or - np.isnan(c[('m',0)]).any() or - np.isnan(c[('dm',0,0)]).any()): - import pdb - pdb.set_trace() - -# #mwf debug -# if c[('u',0)].shape == self.q_shape: -# c[('visPerm',0)]=c[('a',0,0)][:,:,0,0] - -class LevelModel(proteus.Transport.OneLevelTransport): - nCalls=0 - def __init__(self, - uDict, - phiDict, - testSpaceDict, - matType, - dofBoundaryConditionsDict, - dofBoundaryConditionsSetterDict, - coefficients, - elementQuadrature, - elementBoundaryQuadrature, - fluxBoundaryConditionsDict=None, - advectiveFluxBoundaryConditionsSetterDict=None, - diffusiveFluxBoundaryConditionsSetterDictDict=None, - stressTraceBoundaryConditionsSetterDict=None, - stabilization=None, - shockCapturing=None, - conservativeFluxDict=None, - numericalFluxType=None, - TimeIntegrationClass=None, - massLumping=False, - reactionLumping=False, - options=None, - name='defaultName', - reuse_trial_and_test_quadrature=True, - sd = True, - movingDomain=False, - bdyNullSpace=False): - self.bdyNullSpace=bdyNullSpace - # - #set the objects describing the method and boundary conditions - # - self.movingDomain=movingDomain - self.tLast_mesh=None - # - self.name=name - self.sd=sd - self.Hess=False - self.lowmem=True - self.timeTerm=True#allow turning off the time derivative - #self.lowmem=False - self.testIsTrial=True - self.phiTrialIsTrial=True - self.u = uDict - self.ua = {}#analytical solutions - self.phi = phiDict - self.dphi={} - self.matType = matType - #mwf try to reuse test and trial information across components if spaces are the same - self.reuse_test_trial_quadrature = reuse_trial_and_test_quadrature#True#False - if self.reuse_test_trial_quadrature: - for ci in range(1,coefficients.nc): - assert self.u[ci].femSpace.__class__.__name__ == self.u[0].femSpace.__class__.__name__, "to reuse_test_trial_quad all femSpaces must be the same!" - self.u_dof_old = None - ## Simplicial Mesh - self.mesh = self.u[0].femSpace.mesh #assume the same mesh for all components for now - self.testSpace = testSpaceDict - self.dirichletConditions = dofBoundaryConditionsDict - self.dirichletNodeSetList=None #explicit Dirichlet conditions for now, no Dirichlet BC constraints - self.coefficients = coefficients - self.coefficients.initializeMesh(self.mesh) - self.nc = self.coefficients.nc - self.stabilization = stabilization - self.shockCapturing = shockCapturing - self.conservativeFlux = conservativeFluxDict #no velocity post-processing for now - self.fluxBoundaryConditions=fluxBoundaryConditionsDict - self.advectiveFluxBoundaryConditionsSetterDict=advectiveFluxBoundaryConditionsSetterDict - self.diffusiveFluxBoundaryConditionsSetterDictDict = diffusiveFluxBoundaryConditionsSetterDictDict - #determine whether the stabilization term is nonlinear - self.stabilizationIsNonlinear = False - #cek come back - if self.stabilization != None: - for ci in range(self.nc): - if ci in coefficients.mass: - for flag in list(coefficients.mass[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.advection: - for flag in list(coefficients.advection[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.diffusion: - for diffusionDict in list(coefficients.diffusion[ci].values()): - for flag in list(diffusionDict.values()): - if flag != 'constant': - self.stabilizationIsNonlinear=True - if ci in coefficients.potential: - for flag in list(coefficients.potential[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.reaction: - for flag in list(coefficients.reaction[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - if ci in coefficients.hamiltonian: - for flag in list(coefficients.hamiltonian[ci].values()): - if flag == 'nonlinear': - self.stabilizationIsNonlinear=True - #determine if we need element boundary storage - self.elementBoundaryIntegrals = {} - for ci in range(self.nc): - self.elementBoundaryIntegrals[ci] = ((self.conservativeFlux != None) or - (numericalFluxType != None) or - (self.fluxBoundaryConditions[ci] == 'outFlow') or - (self.fluxBoundaryConditions[ci] == 'mixedFlow') or - (self.fluxBoundaryConditions[ci] == 'setFlow')) - # - #calculate some dimensions - # - self.nSpace_global = self.u[0].femSpace.nSpace_global #assume same space dim for all variables - self.nDOF_trial_element = [u_j.femSpace.max_nDOF_element for u_j in list(self.u.values())] - self.nDOF_phi_trial_element = [phi_k.femSpace.max_nDOF_element for phi_k in list(self.phi.values())] - self.n_phi_ip_element = [phi_k.femSpace.referenceFiniteElement.interpolationConditions.nQuadraturePoints for phi_k in list(self.phi.values())] - self.nDOF_test_element = [femSpace.max_nDOF_element for femSpace in list(self.testSpace.values())] - self.nFreeDOF_global = [dc.nFreeDOF_global for dc in list(self.dirichletConditions.values())] - self.nVDOF_element = sum(self.nDOF_trial_element) - self.nFreeVDOF_global = sum(self.nFreeDOF_global) - # - NonlinearEquation.__init__(self,self.nFreeVDOF_global) - # - #build the quadrature point dictionaries from the input (this - #is just for convenience so that the input doesn't have to be - #complete) - # - elementQuadratureDict={} - elemQuadIsDict = isinstance(elementQuadrature,dict) - if elemQuadIsDict: #set terms manually - for I in self.coefficients.elementIntegralKeys: - if I in elementQuadrature: - elementQuadratureDict[I] = elementQuadrature[I] - else: - elementQuadratureDict[I] = elementQuadrature['default'] - else: - for I in self.coefficients.elementIntegralKeys: - elementQuadratureDict[I] = elementQuadrature - if self.stabilization != None: - for I in self.coefficients.elementIntegralKeys: - if elemQuadIsDict: - if I in elementQuadrature: - elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature[I] - else: - elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature['default'] - else: - elementQuadratureDict[('stab',)+I[1:]] = elementQuadrature - if self.shockCapturing != None: - for ci in self.shockCapturing.components: - if elemQuadIsDict: - if ('numDiff',ci,ci) in elementQuadrature: - elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature[('numDiff',ci,ci)] - else: - elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature['default'] - else: - elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature - if massLumping: - for ci in list(self.coefficients.mass.keys()): - elementQuadratureDict[('m',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - for I in self.coefficients.elementIntegralKeys: - elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - if reactionLumping: - for ci in list(self.coefficients.mass.keys()): - elementQuadratureDict[('r',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - for I in self.coefficients.elementIntegralKeys: - elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - elementBoundaryQuadratureDict={} - if isinstance(elementBoundaryQuadrature,dict): #set terms manually - for I in self.coefficients.elementBoundaryIntegralKeys: - if I in elementBoundaryQuadrature: - elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature[I] - else: - elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature['default'] - else: - for I in self.coefficients.elementBoundaryIntegralKeys: - elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature - # - # find the union of all element quadrature points and - # build a quadrature rule for each integral that has a - # weight at each point in the union - #mwf include tag telling me which indices are which quadrature rule? - (self.elementQuadraturePoints,self.elementQuadratureWeights, - self.elementQuadratureRuleIndeces) = Quadrature.buildUnion(elementQuadratureDict) - self.nQuadraturePoints_element = self.elementQuadraturePoints.shape[0] - self.nQuadraturePoints_global = self.nQuadraturePoints_element*self.mesh.nElements_global - # - #Repeat the same thing for the element boundary quadrature - # - (self.elementBoundaryQuadraturePoints, - self.elementBoundaryQuadratureWeights, - self.elementBoundaryQuadratureRuleIndeces) = Quadrature.buildUnion(elementBoundaryQuadratureDict) - self.nElementBoundaryQuadraturePoints_elementBoundary = self.elementBoundaryQuadraturePoints.shape[0] - self.nElementBoundaryQuadraturePoints_global = (self.mesh.nElements_global* - self.mesh.nElementBoundaries_element* - self.nElementBoundaryQuadraturePoints_elementBoundary) -# if isinstance(self.u[0].femSpace,C0_AffineLinearOnSimplexWithNodalBasis): -# print self.nQuadraturePoints_element -# if self.nSpace_global == 3: -# assert(self.nQuadraturePoints_element == 5) -# elif self.nSpace_global == 2: -# assert(self.nQuadraturePoints_element == 6) -# elif self.nSpace_global == 1: -# assert(self.nQuadraturePoints_element == 3) -# -# print self.nElementBoundaryQuadraturePoints_elementBoundary -# if self.nSpace_global == 3: -# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) -# elif self.nSpace_global == 2: -# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 4) -# elif self.nSpace_global == 1: -# assert(self.nElementBoundaryQuadraturePoints_elementBoundary == 1) - - # - #storage dictionaries - self.scalars_element = set() - # - #simplified allocations for test==trial and also check if space is mixed or not - # - self.q={} - self.ebq={} - self.ebq_global={} - self.ebqe={} - self.phi_ip={} - self.edge_based_cfl = np.zeros(self.u[0].dof.shape)+100 - #mesh - #self.q['x'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,3),'d') - self.q[('dV_u', 0)] = (old_div(1.0, self.mesh.nElements_global)) * np.ones((self.mesh.nElements_global, self.nQuadraturePoints_element), 'd') - self.ebqe['x'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,3),'d') - self.q[('u',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') - self.q[('grad(u)',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') - self.q['velocity'] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element,self.nSpace_global),'d') - self.q[('m',0)] = self.q[('u',0)].copy() - self.q[('mt',0)] = self.q[('u',0)].copy() - self.q[('m_last',0)] = self.q[('u',0)].copy() - self.q[('m_tmp',0)] = self.q[('u',0)].copy() - self.q[('cfl',0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') - self.q[('numDiff',0,0)] = np.zeros((self.mesh.nElements_global,self.nQuadraturePoints_element),'d') - self.ebqe[('u',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.ebqe[('grad(u)',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') - self.ebqe['velocity'] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary,self.nSpace_global),'d') - self.ebqe[('advectiveFlux_bc_flag',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'i') - self.ebqe[('advectiveFlux_bc',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.ebqe[('advectiveFlux',0)] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.ebqe[('penalty')] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.points_elementBoundaryQuadrature= set() - self.scalars_elementBoundaryQuadrature= set([('u',ci) for ci in range(self.nc)]) - self.vectors_elementBoundaryQuadrature= set() - self.tensors_elementBoundaryQuadrature= set() - self.inflowBoundaryBC = {} - self.inflowBoundaryBC_values = {} - self.inflowFlux = {} - for cj in range(self.nc): - self.inflowBoundaryBC[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,),'i') - self.inflowBoundaryBC_values[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nDOF_trial_element[cj]),'d') - self.inflowFlux[cj] = np.zeros((self.mesh.nExteriorElementBoundaries_global,self.nElementBoundaryQuadraturePoints_elementBoundary),'d') - self.internalNodes = set(range(self.mesh.nNodes_global)) - #identify the internal nodes this is ought to be in mesh - ##\todo move this to mesh - for ebNE in range(self.mesh.nExteriorElementBoundaries_global): - ebN = self.mesh.exteriorElementBoundariesArray[ebNE] - eN_global = self.mesh.elementBoundaryElementsArray[ebN,0] - ebN_element = self.mesh.elementBoundaryLocalElementBoundariesArray[ebN,0] - for i in range(self.mesh.nNodes_element): - if i != ebN_element: - I = self.mesh.elementNodesArray[eN_global,i] - self.internalNodes -= set([I]) - self.nNodes_internal = len(self.internalNodes) - self.internalNodesArray=np.zeros((self.nNodes_internal,),'i') - for nI,n in enumerate(self.internalNodes): - self.internalNodesArray[nI]=n - # - del self.internalNodes - self.internalNodes = None - logEvent("Updating local to global mappings",2) - self.updateLocal2Global() - logEvent("Building time integration object",2) - logEvent(memory("inflowBC, internalNodes,updateLocal2Global","OneLevelTransport"),level=4) - #mwf for interpolating subgrid error for gradients etc - if self.stabilization and self.stabilization.usesGradientStabilization: - self.timeIntegration = TimeIntegrationClass(self,integrateInterpolationPoints=True) - else: - self.timeIntegration = TimeIntegrationClass(self) - - if options != None: - self.timeIntegration.setFromOptions(options) - logEvent(memory("TimeIntegration","OneLevelTransport"),level=4) - logEvent("Calculating numerical quadrature formulas",2) - self.calculateQuadrature() - #lay out components/equations contiguously for now - self.offset = [0] - for ci in range(1,self.nc): - self.offset += [self.offset[ci-1]+self.nFreeDOF_global[ci-1]] - self.stride = [1 for ci in range(self.nc)] - #use contiguous layout of components for parallel, requires weak DBC's - # mql. Some ASSERTS to restrict the combination of the methods - if self.coefficients.STABILIZATION_TYPE > 0: - pass - #assert self.timeIntegration.isSSP == True, "If STABILIZATION_TYPE>0, use RKEV timeIntegration within VOF model" - #cond = 'levelNonlinearSolver' in dir(options) and (options.levelNonlinearSolver == - # ExplicitLumpedMassMatrixForRichards or options.levelNonlinearSolver == ExplicitConsistentMassMatrixForRichards) - #assert cond, "If STABILIZATION_TYPE>0, use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards or ExplicitConsistentMassMatrixForRichards" - try: - if 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards: - assert self.coefficients.LUMPED_MASS_MATRIX, "If levelNonlinearSolver=ExplicitLumpedMassMatrix, use LUMPED_MASS_MATRIX=True" - except: - pass - if self.coefficients.LUMPED_MASS_MATRIX == True: - cond = self.coefficients.STABILIZATION_TYPE == 2 - assert cond, "Use lumped mass matrix just with: STABILIZATION_TYPE=2 (smoothness based stab.)" - cond = 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards - assert cond, "Use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards when the mass matrix is lumped" - if self.coefficients.FCT == True: - cond = self.coefficients.STABILIZATION_TYPE > 0, "Use FCT just with STABILIZATION_TYPE>0; i.e., edge based stabilization" - # END OF ASSERTS - - # cek adding empty data member for low order numerical viscosity structures here for now - self.ML = None # lumped mass matrix - self.MC_global = None # consistent mass matrix - self.cterm_global = None - self.cterm_transpose_global = None - # dL_global and dC_global are not the full matrices but just the CSR arrays containing the non zero entries - self.residualComputed=False #TMP - self.dLow= None - self.fluxMatrix = None - self.uDotLow = None - self.uLow = None - self.dt_times_dC_minus_dL = None - self.min_s_bc = None - self.max_s_bc = None - # Aux quantity at DOFs to be filled by optimized code (MQL) - self.quantDOFs = np.zeros(self.u[0].dof.shape, 'd') - self.sLow = np.zeros(self.u[0].dof.shape, 'd') - self.sHigh = np.zeros(self.u[0].dof.shape, 'd') - self.sn = np.zeros(self.u[0].dof.shape, 'd') - comm = Comm.get() - self.comm=comm - if comm.size() > 1: - assert numericalFluxType != None and numericalFluxType.useWeakDirichletConditions,"You must use a numerical flux to apply weak boundary conditions for parallel runs" - self.offset = [0] - for ci in range(1,self.nc): - self.offset += [ci] - self.stride = [self.nc for ci in range(self.nc)] - # - logEvent(memory("stride+offset","OneLevelTransport"),level=4) - if numericalFluxType != None: - if options is None or options.periodicDirichletConditions is None: - self.numericalFlux = numericalFluxType(self, - dofBoundaryConditionsSetterDict, - advectiveFluxBoundaryConditionsSetterDict, - diffusiveFluxBoundaryConditionsSetterDictDict) - else: - self.numericalFlux = numericalFluxType(self, - dofBoundaryConditionsSetterDict, - advectiveFluxBoundaryConditionsSetterDict, - diffusiveFluxBoundaryConditionsSetterDictDict, - options.periodicDirichletConditions) - else: - self.numericalFlux = None - #set penalty terms - #cek todo move into numerical flux initialization - if 'penalty' in self.ebq_global: - for ebN in range(self.mesh.nElementBoundaries_global): - for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): - self.ebq_global['penalty'][ebN,k] = old_div(self.numericalFlux.penalty_constant,(self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power)) - #penalty term - #cek move to Numerical flux initialization - if 'penalty' in self.ebqe: - for ebNE in range(self.mesh.nExteriorElementBoundaries_global): - ebN = self.mesh.exteriorElementBoundariesArray[ebNE] - for k in range(self.nElementBoundaryQuadraturePoints_elementBoundary): - self.ebqe['penalty'][ebNE,k] = old_div(self.numericalFlux.penalty_constant,self.mesh.elementBoundaryDiametersArray[ebN]**self.numericalFlux.penalty_power) - logEvent(memory("numericalFlux","OneLevelTransport"),level=4) - self.elementEffectiveDiametersArray = self.mesh.elementInnerDiametersArray - #use post processing tools to get conservative fluxes, None by default - from proteus import PostProcessingTools - self.velocityPostProcessor = PostProcessingTools.VelocityPostProcessingChooser(self) - logEvent(memory("velocity postprocessor","OneLevelTransport"),level=4) - #helper for writing out data storage - from proteus import Archiver - self.elementQuadratureDictionaryWriter = Archiver.XdmfWriter() - self.elementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() - self.exteriorElementBoundaryQuadratureDictionaryWriter = Archiver.XdmfWriter() - #TODO get rid of this - for ci,fbcObject in list(self.fluxBoundaryConditionsObjectsDict.items()): - self.ebqe[('advectiveFlux_bc_flag',ci)] = np.zeros(self.ebqe[('advectiveFlux_bc',ci)].shape,'i') - for t,g in list(fbcObject.advectiveFluxBoundaryConditionsDict.items()): - if ci in self.coefficients.advection: - self.ebqe[('advectiveFlux_bc',ci)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) - self.ebqe[('advectiveFlux_bc_flag',ci)][t[0],t[1]] = 1 - - if hasattr(self.numericalFlux,'setDirichletValues'): - self.numericalFlux.setDirichletValues(self.ebqe) - if not hasattr(self.numericalFlux,'isDOFBoundary'): - self.numericalFlux.isDOFBoundary = {0:np.zeros(self.ebqe[('u',0)].shape,'i')} - if not hasattr(self.numericalFlux,'ebqe'): - self.numericalFlux.ebqe = {('u',0):np.zeros(self.ebqe[('u',0)].shape,'d')} - #TODO how to handle redistancing calls for calculateCoefficients,calculateElementResidual etc - self.globalResidualDummy = None - compKernelFlag=0 - self.delta_x_ij=None - self.richards = cRichards_base(self.nSpace_global, - self.nQuadraturePoints_element, - self.u[0].femSpace.elementMaps.localFunctionSpace.dim, - self.u[0].femSpace.referenceFiniteElement.localFunctionSpace.dim, - self.testSpace[0].referenceFiniteElement.localFunctionSpace.dim, - self.nElementBoundaryQuadraturePoints_elementBoundary, - compKernelFlag) - if self.movingDomain: - self.MOVING_DOMAIN=1.0 - else: - self.MOVING_DOMAIN=0.0 - #cek hack - self.movingDomain=False - self.MOVING_DOMAIN=0.0 - if self.mesh.nodeVelocityArray is None: - self.mesh.nodeVelocityArray = np.zeros(self.mesh.nodeArray.shape,'d') - self.forceStrongConditions=self.coefficients.forceStrongConditions - self.dirichletConditionsForceDOF = {} - if self.forceStrongConditions: - for cj in range(self.nc): - self.dirichletConditionsForceDOF[cj] = DOFBoundaryConditions(self.u[cj].femSpace,dofBoundaryConditionsSetterDict[cj],weakDirichletConditions=False) - def FCTStep(self): - import pdb - rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() - limited_solution = np.zeros((len(rowptr) - 1),'d') - #self.u_free_dof_stage_0_l = np.zeros((len(rowptr) - 1),'d') - #self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage], # soln - #fromFreeToGlobal=0 - #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - # self.offset[0], - # self.stride[0], - # self.dirichletConditions[0].global2freeGlobal_global_dofs, - # self.dirichletConditions[0].global2freeGlobal_free_dofs, - # self.u_free_dof_stage_0_l, - # self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage]) - argsDict = cArgumentsDict.ArgumentsDict() - argsDict["bc_mask"] = self.bc_mask - argsDict["NNZ"] = self.nnz - argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs - argsDict["dt"] = self.timeIntegration.dt - argsDict["lumped_mass_matrix"] = self.ML - argsDict["soln"] = self.sn - argsDict["pn"] = self.u[0].dof - argsDict["solH"] = self.sHigh - argsDict["uLow"] = self.sLow - argsDict["uDotLow"] = self.uDotLow - argsDict["limited_solution"] = limited_solution - argsDict["csrRowIndeces_DofLoops"] = rowptr - argsDict["csrColumnOffsets_DofLoops"] = colind - argsDict["MassMatrix"] = MassMatrix - argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL - argsDict["min_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0]) #cek hack just set from physical bounds - argsDict["max_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0] + self.coefficients.thetaSR_types[0]) #cek hack - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - argsDict["MONOLITHIC"] =0#cek hack self.coefficients.MONOLITHIC - #pdb.set_trace() - self.richards.FCTStep(argsDict) - - # self.nnz, # number of non zero entries - # len(rowptr) - 1, # number of DOFs - # self.timeIntegration.dt, - # self.ML, # Lumped mass matrix - # self.sn, - # self.u_dof_old, - # self.sHigh, # high order solution - # self.sLow, - # limited_solution, - # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) - # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) - # MassMatrix, - # self.dt_times_dC_minus_dL, - # self.min_s_bc, - # self.max_s_bc, - # self.coefficients.LUMPED_MASS_MATRIX, - # self.coefficients.MONOLITHIC) - old_dof = self.u[0].dof.copy() - self.invert(limited_solution, self.u[0].dof) - self.timeIntegration.u[:] = self.u[0].dof - #fromFreeToGlobal=1 #direction copying - #cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - # self.offset[0], - # self.stride[0], - # self.dirichletConditions[0].global2freeGlobal_global_dofs, - # self.dirichletConditions[0].global2freeGlobal_free_dofs, - # self.u[0].dof, - # limited_solution) - def kth_FCT_step(self): - #import pdb - #pdb.set_trace() - rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() - limitedFlux = np.zeros(self.nnz) - limited_solution = np.zeros((len(rowptr) - 1),'d') - #limited_solution[:] = self.timeIntegration.u_dof_stage[0][self.timeIntegration.lstage] - fromFreeToGlobal=0 #direction copying - cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - self.offset[0], - self.stride[0], - self.dirichletConditions[0].global2freeGlobal_global_dofs, - self.dirichletConditions[0].global2freeGlobal_free_dofs, - limited_solution, - self.timeintegration.u_dof_stage[0][self.timeIntegration.lstage]) - - self.richards.kth_FCT_step( - self.timeIntegration.dt, - self.coefficients.num_fct_iter, - self.nnz, # number of non zero entries - len(rowptr) - 1, # number of DOFs - MassMatrix, - self.ML, # Lumped mass matrix - self.u_dof_old, - limited_solution, - self.uDotLow, - self.uLow, - self.dLow, - self.fluxMatrix, - limitedFlux, - rowptr, - colind) - - self.timeIntegration.u[:] = limited_solution - #self.u[0].dof[:] = limited_solution - fromFreeToGlobal=1 #direction copying - cfemIntegrals.copyBetweenFreeUnknownsAndGlobalUnknowns(fromFreeToGlobal, - self.offset[0], - self.stride[0], - self.dirichletConditions[0].global2freeGlobal_global_dofs, - self.dirichletConditions[0].global2freeGlobal_free_dofs, - self.u[0].dof, - limited_solution) - def calculateCoefficients(self): - pass - def calculateElementResidual(self): - if self.globalResidualDummy != None: - self.getResidual(self.u[0].dof,self.globalResidualDummy) - def getResidual(self,u,r): - import pdb - import copy - """ - Calculate the element residuals and add in to the global residual - """ - cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, - self.jacobian) - if self.u_dof_old is None: - # Pass initial condition to u_dof_old - self.u_dof_old = np.copy(self.u[0].dof) - rowptr, colind, nzval = self.jacobian.getCSRrepresentation() - nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix - r.fill(0.0) - ######################## - ### COMPUTE C MATRIX ### - ######################## - if self.cterm_global is None: - # since we only need cterm_global to persist, we can drop the other self.'s - self.cterm = {} - self.cterm_a = {} - self.cterm_global = {} - self.cterm_transpose = {} - self.cterm_a_transpose = {} - self.cterm_global_transpose = {} - rowptr, colind, nzval = self.jacobian.getCSRrepresentation() - nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix - di = self.q[('grad(u)', 0)].copy() # direction of derivative - # JACOBIANS (FOR ELEMENT TRANSFORMATION) - self.q[('J')] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nSpace_global, - self.nSpace_global), - 'd') - self.q[('inverse(J)')] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nSpace_global, - self.nSpace_global), - 'd') - self.q[('det(J)')] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element), - 'd') - self.u[0].femSpace.elementMaps.getJacobianValues(self.elementQuadraturePoints, - self.q['J'], - self.q['inverse(J)'], - self.q['det(J)']) - self.q['abs(det(J))'] = np.abs(self.q['det(J)']) - # SHAPE FUNCTIONS - self.q[('w', 0)] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nDOF_test_element[0]), - 'd') - self.q[('w*dV_m', 0)] = self.q[('w', 0)].copy() - self.u[0].femSpace.getBasisValues(self.elementQuadraturePoints, self.q[('w', 0)]) - cfemIntegrals.calculateWeightedShape(self.elementQuadratureWeights[('u', 0)], - self.q['abs(det(J))'], - self.q[('w', 0)], - self.q[('w*dV_m', 0)]) - # GRADIENT OF TEST FUNCTIONS - self.q[('grad(w)', 0)] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nDOF_test_element[0], - self.nSpace_global), - 'd') - self.u[0].femSpace.getBasisGradientValues(self.elementQuadraturePoints, - self.q['inverse(J)'], - self.q[('grad(w)', 0)]) - self.q[('grad(w)*dV_f', 0)] = np.zeros((self.mesh.nElements_global, - self.nQuadraturePoints_element, - self.nDOF_test_element[0], - self.nSpace_global), - 'd') - cfemIntegrals.calculateWeightedShapeGradients(self.elementQuadratureWeights[('u', 0)], - self.q['abs(det(J))'], - self.q[('grad(w)', 0)], - self.q[('grad(w)*dV_f', 0)]) - ########################## - ### LUMPED MASS MATRIX ### - ########################## - # assume a linear mass term - dm = np.ones(self.q[('u', 0)].shape, 'd') - elementMassMatrix = np.zeros((self.mesh.nElements_global, - self.nDOF_test_element[0], - self.nDOF_trial_element[0]), 'd') - cfemIntegrals.updateMassJacobian_weak_lowmem(dm, - self.q[('w', 0)], - self.q[('w*dV_m', 0)], - elementMassMatrix) - self.MC_a = nzval.copy() - self.MC_global = SparseMat(self.nFreeDOF_global[0], - self.nFreeDOF_global[0], - nnz, - self.MC_a, - colind, - rowptr) - cfemIntegrals.zeroJacobian_CSR(self.nnz, self.MC_global) - cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.csrRowIndeces[(0, 0)], - self.csrColumnOffsets[(0, 0)], - elementMassMatrix, - self.MC_global) - self.ML = np.zeros((self.nFreeDOF_global[0],), 'd') - for i in range(self.nFreeDOF_global[0]): - self.ML[i] = self.MC_a[rowptr[i]:rowptr[i + 1]].sum() - np.testing.assert_almost_equal(self.ML.sum(), - self.mesh.volume, - err_msg="Trace of lumped mass matrix should be the domain volume", verbose=True) - for d in range(self.nSpace_global): # spatial dimensions - # C matrices - self.cterm[d] = np.zeros((self.mesh.nElements_global, - self.nDOF_test_element[0], - self.nDOF_trial_element[0]), 'd') - self.cterm_a[d] = nzval.copy() - #self.cterm_a[d] = np.zeros(nzval.size) - self.cterm_global[d] = SparseMat(self.nFreeDOF_global[0], - self.nFreeDOF_global[0], - nnz, - self.cterm_a[d], - colind, - rowptr) - cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global[d]) - di[:] = 0.0 - di[..., d] = 1.0 - cfemIntegrals.updateHamiltonianJacobian_weak_lowmem(di, - self.q[('grad(w)*dV_f', 0)], - self.q[('w', 0)], - self.cterm[d]) # int[(di*grad(wj))*wi*dV] - cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.csrRowIndeces[(0, 0)], - self.csrColumnOffsets[(0, 0)], - self.cterm[d], - self.cterm_global[d]) - # C Transpose matrices - self.cterm_transpose[d] = np.zeros((self.mesh.nElements_global, - self.nDOF_test_element[0], - self.nDOF_trial_element[0]), 'd') - self.cterm_a_transpose[d] = nzval.copy() - self.cterm_global_transpose[d] = SparseMat(self.nFreeDOF_global[0], - self.nFreeDOF_global[0], - nnz, - self.cterm_a_transpose[d], - colind, - rowptr) - cfemIntegrals.zeroJacobian_CSR(self.nnz, self.cterm_global_transpose[d]) - di[:] = 0.0 - di[..., d] = -1.0 - cfemIntegrals.updateAdvectionJacobian_weak_lowmem(di, - self.q[('w', 0)], - self.q[('grad(w)*dV_f', 0)], - self.cterm_transpose[d]) # -int[(-di*grad(wi))*wj*dV] - cfemIntegrals.updateGlobalJacobianFromElementJacobian_CSR(self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.l2g[0]['nFreeDOF'], - self.l2g[0]['freeLocal'], - self.csrRowIndeces[(0, 0)], - self.csrColumnOffsets[(0, 0)], - self.cterm_transpose[d], - self.cterm_global_transpose[d]) - - rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() - else: - Cy = np.zeros(Cx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() - else: - Cz = np.zeros(Cx.shape, 'd') - rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() - else: - CTy = np.zeros(CTx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() - else: - CTz = np.zeros(CTx.shape, 'd') - - # This is dummy. I just care about the csr structure of the sparse matrix - self.dLow = np.zeros(Cx.shape, 'd') - self.fluxMatrix = np.zeros(Cx.shape, 'd') - self.dt_times_dC_minus_dL = np.zeros(Cx.shape, 'd') - nFree = len(rowptr)-1 - self.min_s_bc = np.zeros(nFree, 'd') + 1E10 - self.max_s_bc = np.zeros(nFree, 'd') - 1E10 - self.uDotLow = np.zeros(nFree, 'd') - self.uLow = np.zeros(nFree, 'd') - # - # cek end computationa of cterm_global - # - # cek showing mquezada an example of using cterm_global sparse matrix - # calculation y = c*x where x==1 - # direction=0 - #rowptr, colind, c = self.cterm_global[direction].getCSRrepresentation() - #y = np.zeros((self.nFreeDOF_global[0],),'d') - #x = np.ones((self.nFreeDOF_global[0],),'d') - # ij=0 - # for i in range(self.nFreeDOF_global[0]): - # for offset in range(rowptr[i],rowptr[i+1]): - # j = colind[offset] - # y[i] += c[ij]*x[j] - # ij+=1 - #Load the unknowns into the finite element dof - self.timeIntegration.calculateCoefs() - self.timeIntegration.calculateU(u) - self.setUnknowns(self.timeIntegration.u) - #cek can put in logic to skip of BC's don't depend on t or u - #Dirichlet boundary conditions - self.numericalFlux.setDirichletValues(self.ebqe) - #flux boundary conditions - #cek hack, just using advective flux for flux BC for now - for t,g in list(self.fluxBoundaryConditionsObjectsDict[0].advectiveFluxBoundaryConditionsDict.items()): - self.ebqe[('advectiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) - self.ebqe[('advectiveFlux_bc_flag',0)][t[0],t[1]] = 1 - # for t,g in self.fluxBoundaryConditionsObjectsDict[0].diffusiveFluxBoundaryConditionsDict.iteritems(): - # self.ebqe[('diffusiveFlux_bc',0)][t[0],t[1]] = g(self.ebqe[('x')][t[0],t[1]],self.timeIntegration.t) - # self.ebqe[('diffusiveFlux_bc_flag',0)][t[0],t[1]] = 1 - #self.shockCapturing.lag=True - if self.forceStrongConditions: - self.bc_mask = np.ones_like(self.u[0].dof) - for cj in range(len(self.dirichletConditionsForceDOF)): - for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): - self.u[cj].dof[dofN] = g(self.dirichletConditionsForceDOF[cj].DOFBoundaryPointDict[dofN],self.timeIntegration.t) - self.u_dof_old[dofN] = self.u[cj].dof[dofN] - self.bc_mask[dofN] = 0.0 - degree_polynomial = 1 - try: - degree_polynomial = self.u[0].femSpace.order - except: - pass - - argsDict = cArgumentsDict.ArgumentsDict() - if self.forceStrongConditions: - argsDict["bc_mask"] = self.bc_mask - argsDict["dt"] = self.timeIntegration.dt - argsDict["Theta"] = 1.0 - argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi - argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi - argsDict["mesh_dof"] = self.mesh.nodeArray - argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray - argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN - argsDict["mesh_l2g"] = self.mesh.elementNodesArray - argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] - argsDict["u_trial_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi - argsDict["u_test_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi - argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace - argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace - argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] - argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals - argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians - argsDict["nElements_global"] = self.mesh.nElements_global - argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] - argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, - argsDict["isSeepageFace"] = self.coefficients.isSeepageFace - argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] - argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] - argsDict["rho"] = self.coefficients.rho - argsDict["beta"] = self.coefficients.beta - argsDict["gravity"] = self.coefficients.gravity - argsDict["alpha"] = self.coefficients.vgm_alpha_types - argsDict["n"] = self.coefficients.vgm_n_types - argsDict["thetaR"] = self.coefficients.thetaR_types - argsDict["thetaSR"] = self.coefficients.thetaSR_types - argsDict["KWs"] = self.coefficients.Ksw_types - argsDict["useMetrics"] = 0.0 - argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf - argsDict["lag_shockCapturing"] = 0 - argsDict["shockCapturingDiffusion"] = 0.0 - argsDict["sc_uref"] = 0.0 - argsDict["sc_alpha"] = 0.0 - argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g - argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] - argsDict["elementDiameter"] = self.mesh.elementDiametersArray - argsDict["degree_polynomial"] = degree_polynomial - argsDict["u_dof"] = self.u[0].dof - argsDict["u_dof_old"] = self.u_dof_old - argsDict["velocity"] = self.q['velocity'] - argsDict["q_m"] = self.timeIntegration.m_tmp[0] - argsDict["q_u"] = self.q[('u',0)] - argsDict["q_dV"] = self.q[('dV_u',0)] - argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] - argsDict["cfl"] = self.q[('cfl',0)] - argsDict["q_numDiff_u"] = self.q[('cfl',0)] - argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] - argsDict["offset_u"] = self.offset[0] - argsDict["stride_u"] = self.stride[0] - argsDict["globalResidual"] = r - argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global - argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray - argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray - argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray - argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] - argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] - argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] - argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] - argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] - argsDict["ebqe_phi"] = self.ebqe[('u',0)] - argsDict["epsFact"] = 0.0 - argsDict["ebqe_u"] = self.ebqe[('u',0)] - argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] - argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE - # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION - argsDict["cE"] = self.coefficients.cE - argsDict["cK"] = self.coefficients.cK - # PARAMETERS FOR LOG BASED ENTROPY FUNCTION - argsDict["uL"] = self.coefficients.uL - argsDict["uR"] = self.coefficients.uR - # PARAMETERS FOR EDGE VISCOSITY - argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs - argsDict["NNZ"] = self.nnz - argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern - argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) - argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) - argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms - argsDict["globalJacobian"] = self.jacobian.getCSRrepresentation()[2] - # C matrices - argsDict["Cx"] = Cx - argsDict["Cy"] = Cy - argsDict["Cz"] = Cz - argsDict["CTx"] = CTx - argsDict["CTy"] = CTy - argsDict["CTz"] = CTz - argsDict["ML"] = self.ML - argsDict["delta_x_ij"] = self.delta_x_ij - # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE - argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE - # FLUX CORRECTED TRANSPORT - argsDict["dLow"] = self.dLow - argsDict["fluxMatrix"] = self.fluxMatrix - argsDict["uDotLow"] = self.uDotLow - argsDict["uLow"] = self.uLow - argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL - argsDict["min_s_bc"] = self.min_s_bc - argsDict["max_s_bc"] = self.max_s_bc - argsDict["quantDOFs"] = self.quantDOFs - argsDict["sLow"] = self.sLow - argsDict["sn"] = self.sn - if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG - self.calculateResidual = self.richards.calculateResidual - self.calculateJacobian = self.richards.calculateJacobian - else: - self.calculateResidual = self.richards.calculateResidual_entropy_viscosity - self.calculateJacobian = self.richards.calculateMassMatrix - if self.delta_x_ij is None: - self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') - self.calculateResidual(argsDict) - #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] - #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf - #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] - #self.timeIntegration.calculateElementCoefficients(self.q) - if self.forceStrongConditions:# - for cj in range(len(self.dirichletConditionsForceDOF)):# - for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): - r[self.offset[cj]+self.stride[cj]*dofN] = 0 - if self.stabilization: - self.stabilization.accumulateSubgridMassHistory(self.q) - logEvent("Global residual",level=9,data=r) - self.nonlinear_function_evaluations += 1 - if self.globalResidualDummy is None: - self.globalResidualDummy = np.zeros(r.shape,'d') - - def invert(self,u,r): - #u=s - #r=p - import pdb - import copy - """ - Calculate the element residuals and add in to the global residual - """ - self.sHigh[:] = u - rowptr, colind, nzval = self.jacobian.getCSRrepresentation() - nnz = nzval.shape[-1] # number of non-zero entries in sparse matrix - r.fill(0.0) - rowptr, colind, Cx = self.cterm_global[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, Cy = self.cterm_global[1].getCSRrepresentation() - else: - Cy = np.zeros(Cx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, Cz = self.cterm_global[2].getCSRrepresentation() - else: - Cz = np.zeros(Cx.shape, 'd') - rowptr, colind, CTx = self.cterm_global_transpose[0].getCSRrepresentation() - if (self.nSpace_global == 2): - rowptr, colind, CTy = self.cterm_global_transpose[1].getCSRrepresentation() - else: - CTy = np.zeros(CTx.shape, 'd') - if (self.nSpace_global == 3): - rowptr, colind, CTz = self.cterm_global_transpose[2].getCSRrepresentation() - else: - CTz = np.zeros(CTx.shape, 'd') - - # This is dummy. I just care about the csr structure of the sparse matrix - nFree = len(rowptr)-1 - degree_polynomial = 1 - try: - degree_polynomial = self.u[0].femSpace.order - except: - pass - if self.delta_x_ij is None: - self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') - argsDict = cArgumentsDict.ArgumentsDict() - argsDict["dt"] = self.timeIntegration.dt - argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi - argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi - argsDict["mesh_dof"] = self.mesh.nodeArray - argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray - argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN - argsDict["mesh_l2g"] = self.mesh.elementNodesArray - argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] - argsDict["u_trial_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi - argsDict["u_test_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi - argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace - argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace - argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] - argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals - argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians - argsDict["nElements_global"] = self.mesh.nElements_global - argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] - argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, - argsDict["isSeepageFace"] = self.coefficients.isSeepageFace - argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] - argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] - argsDict["rho"] = self.coefficients.rho - argsDict["beta"] = self.coefficients.beta - argsDict["gravity"] = self.coefficients.gravity - argsDict["alpha"] = self.coefficients.vgm_alpha_types - argsDict["n"] = self.coefficients.vgm_n_types - argsDict["thetaR"] = self.coefficients.thetaR_types - argsDict["thetaSR"] = self.coefficients.thetaSR_types - argsDict["KWs"] = self.coefficients.Ksw_types - argsDict["useMetrics"] = 0.0 - argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf - argsDict["lag_shockCapturing"] = 0 - argsDict["shockCapturingDiffusion"] = 0.0 - argsDict["sc_uref"] = 0.0 - argsDict["sc_alpha"] = 0.0 - argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g - argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] - argsDict["elementDiameter"] = self.mesh.elementDiametersArray - argsDict["degree_polynomial"] = degree_polynomial - argsDict["u_dof"] = u#self.u[0].dof - argsDict["u_dof_old"] = self.u[0].dof - argsDict["velocity"] = self.q['velocity'] - argsDict["q_m"] = self.timeIntegration.m_tmp[0] - argsDict["q_u"] = self.q[('u',0)] - argsDict["q_dV"] = self.q[('dV_u',0)] - argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] - argsDict["cfl"] = self.q[('cfl',0)] - argsDict["q_numDiff_u"] = self.q[('cfl',0)] - argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] - argsDict["offset_u"] = self.offset[0] - argsDict["stride_u"] = self.stride[0] - argsDict["globalResidual"] = r - argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global - argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray - argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray - argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray - argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] - argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] - argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] - argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] - argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] - argsDict["ebqe_phi"] = self.ebqe[('u',0)] - argsDict["epsFact"] = 0.0 - argsDict["ebqe_u"] = self.ebqe[('u',0)] - argsDict["ebqe_flux"] = self.ebqe[('advectiveFlux',0)] - argsDict['STABILIZATION_TYPE'] = self.coefficients.STABILIZATION_TYPE - # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION - argsDict["cE"] = self.coefficients.cE - argsDict["cK"] = self.coefficients.cK - # PARAMETERS FOR LOG BASED ENTROPY FUNCTION - argsDict["uL"] = self.coefficients.uL - argsDict["uR"] = self.coefficients.uR - # PARAMETERS FOR EDGE VISCOSITY - argsDict["numDOFs"] = len(rowptr) - 1 # num of DOFs - argsDict["NNZ"] = self.nnz - argsDict["Cx"] = len(Cx) # num of non-zero entries in the sparsity pattern - argsDict["csrRowIndeces_DofLoops"] = rowptr # Row indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrColumnOffsets_DofLoops"] = colind # Column indices for Sparsity Pattern (convenient for DOF loops) - argsDict["csrRowIndeces_CellLoops"] = self.csrRowIndeces[(0, 0)] # row indices (convenient for element loops) - argsDict["csrColumnOffsets_CellLoops"] = self.csrColumnOffsets[(0, 0)] # column indices (convenient for element loops) - argsDict["csrColumnOffsets_eb_CellLoops"] = self.csrColumnOffsets_eb[(0, 0)] # indices for boundary terms - # C matrices - argsDict["Cx"] = Cx - argsDict["Cy"] = Cy - argsDict["Cz"] = Cz - argsDict["CTx"] = CTx - argsDict["CTy"] = CTy - argsDict["CTz"] = CTz - argsDict["ML"] = self.ML - argsDict["delta_x_ij"] = self.delta_x_ij - # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - argsDict["STABILIZATTION_TYPE"] = self.coefficients.STABILIZATION_TYPE - argsDict["ENTROPY_TYPE"] = self.coefficients.ENTROPY_TYPE - # FLUX CORRECTED TRANSPORT - argsDict["dLow"] = self.dLow - argsDict["fluxMatrix"] = self.fluxMatrix - argsDict["uDotLow"] = self.uDotLow - argsDict["uLow"] = self.uLow - argsDict["dt_times_fH_minus_fL"] = self.dt_times_dC_minus_dL - argsDict["min_s_bc"] = self.min_s_bc - argsDict["max_s_bc"] = self.max_s_bc - argsDict["quantDOFs"] = self.quantDOFs - argsDict["sLow"] = self.sLow - argsDict["sn"] = self.sn - self.richards.invert(argsDict) - # self.timeIntegration.dt, - # self.u[0].femSpace.elementMaps.psi, - # self.u[0].femSpace.elementMaps.grad_psi, - # self.mesh.nodeArray, - # self.mesh.nodeVelocityArray, - # self.MOVING_DOMAIN, - # self.mesh.elementNodesArray, - # self.elementQuadratureWeights[('u',0)], - # self.u[0].femSpace.psi, - # self.u[0].femSpace.grad_psi, - # self.u[0].femSpace.psi, - # self.u[0].femSpace.grad_psi, - # #element boundary - # self.u[0].femSpace.elementMaps.psi_trace, - # self.u[0].femSpace.elementMaps.grad_psi_trace, - # self.elementBoundaryQuadratureWeights[('u',0)], - # self.u[0].femSpace.psi_trace, - # self.u[0].femSpace.grad_psi_trace, - # self.u[0].femSpace.psi_trace, - # self.u[0].femSpace.grad_psi_trace, - # self.u[0].femSpace.elementMaps.boundaryNormals, - # self.u[0].femSpace.elementMaps.boundaryJacobians, - # #physics - # self.mesh.nElements_global, - # self.ebqe['penalty'],#double* ebqe_penalty_ext, - # self.mesh.elementMaterialTypes,#int* elementMaterialTypes, - # self.coefficients.isSeepageFace, - # self.coefficients.sdInfo[(0,0)][0],#int* a_rowptr, - # self.coefficients.sdInfo[(0,0)][1],#int* a_colind, - # self.coefficients.rho,#double rho, - # self.coefficients.beta,#double beta, - # self.coefficients.gravity,#double* gravity, - # self.coefficients.vgm_alpha_types,#double* alpha, - # self.coefficients.vgm_n_types,#double* n, - # self.coefficients.thetaR_types,#double* thetaR, - # self.coefficients.thetaSR_types,#double* thetaSR, - # self.coefficients.Ksw_types,#double* KWs, - # False,#self.coefficients.useMetrics, - # self.timeIntegration.alpha_bdf, - # 0,#self.shockCapturing.lag, - # 0.0,#cek hack self.shockCapturing.shockCapturingFactor, - # 0.0,#self.coefficients.sc_uref, - # 0.0,#self.coefficients.sc_beta, - # self.u[0].femSpace.dofMap.l2g, - # self.l2g[0]['freeGlobal'], - # self.mesh.elementDiametersArray, - # degree_polynomial, - # self.sHigh, - # self.u_dof_old, - # self.q['velocity'],#self.coefficients.q_v, - # self.timeIntegration.m_tmp[0], - # self.q[('u',0)], - # self.timeIntegration.beta_bdf[0], - # self.q[('cfl',0)], - # self.edge_based_cfl, - # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff[0], - # self.q[('cfl',0)],#cek hack self.shockCapturing.numDiff_last[0], - # self.offset[0],self.stride[0], - # r, - # self.mesh.nExteriorElementBoundaries_global, - # self.mesh.exteriorElementBoundariesArray, - # self.mesh.elementBoundaryElementsArray, - # self.mesh.elementBoundaryLocalElementBoundariesArray, - # self.ebqe['velocity'],#self.coefficients.ebqe_v, - # self.numericalFlux.isDOFBoundary[0], - # self.numericalFlux.ebqe[('u',0)], - # self.ebqe[('advectiveFlux_bc_flag',0)], - # self.ebqe[('advectiveFlux_bc',0)], - # self.ebqe[('u',0)],#cek hack self.coefficients.ebqe_phi, - # 0.0,#cek hack self.coefficients.epsFact, - # self.ebqe[('u',0)], - # self.ebqe[('advectiveFlux',0)], - # # ENTROPY VISCOSITY and ARTIFICIAL COMRPESSION - # self.coefficients.cE, - # self.coefficients.cK, - # # PARAMETERS FOR LOG BASED ENTROPY FUNCTION - # self.coefficients.uL, - # self.coefficients.uR, - # # PARAMETERS FOR EDGE VISCOSITY - # len(rowptr) - 1, # num of DOFs - # len(Cx), # num of non-zero entries in the sparsity pattern - # rowptr, # Row indices for Sparsity Pattern (convenient for DOF loops) - # colind, # Column indices for Sparsity Pattern (convenient for DOF loops) - # self.csrRowIndeces[(0, 0)], # row indices (convenient for element loops) - # self.csrColumnOffsets[(0, 0)], # column indices (convenient for element loops) - # self.csrColumnOffsets_eb[(0, 0)], # indices for boundary terms - # # C matrices - # Cx, - # Cy, - # Cz, - # CTx, - # CTy, - # CTz, - # self.ML, - # self.delta_x_ij, - # # PARAMETERS FOR 1st or 2nd ORDER MPP METHOD - # self.coefficients.LUMPED_MASS_MATRIX, - # self.coefficients.STABILIZATION_TYPE, - # self.coefficients.ENTROPY_TYPE, - # # FLUX CORRECTED TRANSPORT - # self.dLow, - # self.fluxMatrix, - # self.uDotLow, - # self.uLow, - # self.dt_times_dC_minus_dL, - # self.min_s_bc, - # self.max_s_bc, - # self.quantDOFs) - #self.q[('mt',0)][:] =self.timeIntegration.m_tmp[0] - #self.q[('mt',0)] *= self.timeIntegration.alpha_bdf - #self.q[('mt',0)] += self.timeIntegration.beta_bdf[0] - #self.timeIntegration.calculateElementCoefficients(self.q) - #if self.forceStrongConditions:# - # for cj in range(len(self.dirichletConditionsForceDOF)):# - # for dofN,g in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.items()): - # r[self.offset[cj]+self.stride[cj]*dofN] = 0 - #if self.stabilization: - # self.stabilization.accumulateSubgridMassHistory(self.q) - #logEvent("Global residual",level=9,data=r) - #self.nonlinear_function_evaluations += 1 - #if self.globalResidualDummy is None: - # self.globalResidualDummy = numpy.zeros(r.shape,'d') - def getJacobian(self,jacobian): - if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG - cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, - jacobian) - degree_polynomial = 1 - try: - degree_polynomial = self.u[0].femSpace.order - except: - pass - if self.delta_x_ij is None: - self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') - argsDict = cArgumentsDict.ArgumentsDict() - argsDict["dt"] = self.timeIntegration.dt - argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi - argsDict["mesh_grad_trial_ref"] = self.u[0].femSpace.elementMaps.grad_psi - argsDict["mesh_dof"] = self.mesh.nodeArray - argsDict["mesh_velocity_dof"] = self.mesh.nodeVelocityArray - argsDict["MOVING_DOMAIN"] = self.MOVING_DOMAIN - argsDict["mesh_l2g"] = self.mesh.elementNodesArray - argsDict["dV_ref"] = self.elementQuadratureWeights[('u',0)] - argsDict["u_trial_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_trial_ref"] = self.u[0].femSpace.grad_psi - argsDict["u_test_ref"] = self.u[0].femSpace.psi - argsDict["u_grad_test_ref"] = self.u[0].femSpace.grad_psi - argsDict["mesh_trial_trace_ref"] = self.u[0].femSpace.elementMaps.psi_trace - argsDict["mesh_grad_trial_trace_ref"] = self.u[0].femSpace.elementMaps.grad_psi_trace - argsDict["dS_ref"] = self.elementBoundaryQuadratureWeights[('u',0)] - argsDict["u_trial_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_trial_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["u_test_trace_ref"] = self.u[0].femSpace.psi_trace - argsDict["u_grad_test_trace_ref"] = self.u[0].femSpace.grad_psi_trace - argsDict["normal_ref"] = self.u[0].femSpace.elementMaps.boundaryNormals - argsDict["boundaryJac_ref"] = self.u[0].femSpace.elementMaps.boundaryJacobians - argsDict["nElements_global"] = self.mesh.nElements_global - argsDict["ebqe_penalty_ext"] = self.ebqe['penalty'] - argsDict["elementMaterialTypes"] = self.mesh.elementMaterialTypes, - argsDict["isSeepageFace"] = self.coefficients.isSeepageFace - argsDict["a_rowptr"] = self.coefficients.sdInfo[(0,0)][0] - argsDict["a_colind"] = self.coefficients.sdInfo[(0,0)][1] - argsDict["rho"] = self.coefficients.rho - argsDict["beta"] = self.coefficients.beta - argsDict["gravity"] = self.coefficients.gravity - argsDict["alpha"] = self.coefficients.vgm_alpha_types - argsDict["n"] = self.coefficients.vgm_n_types - argsDict["thetaR"] = self.coefficients.thetaR_types - argsDict["thetaSR"] = self.coefficients.thetaSR_types - argsDict["KWs"] = self.coefficients.Ksw_types - argsDict["useMetrics"] = 0.0 - argsDict["alphaBDF"] = self.timeIntegration.alpha_bdf - argsDict["lag_shockCapturing"] = 0 - argsDict["shockCapturingDiffusion"] = 0.0 - argsDict["u_l2g"] = self.u[0].femSpace.dofMap.l2g - argsDict["r_l2g"] = self.l2g[0]['freeGlobal'] - argsDict["elementDiameter"] = self.mesh.elementDiametersArray - argsDict["degree_polynomial"] = degree_polynomial - argsDict["u_dof"] = self.u[0].dof - argsDict["velocity"] = self.q['velocity'] - argsDict["q_m_betaBDF"] = self.timeIntegration.beta_bdf[0] - argsDict["cfl"] = self.q[('cfl',0)] - argsDict["q_numDiff_u_last"] = self.q[('cfl',0)] - argsDict["csrRowIndeces_u_u"] = self.csrRowIndeces[(0,0)] - argsDict["csrColumnOffsets_u_u"] = self.csrColumnOffsets[(0,0)] - argsDict["globalJacobian"] = jacobian.getCSRrepresentation()[2] - argsDict["delta_x_ij"] = self.delta_x_ij - argsDict["nExteriorElementBoundaries_global"] = self.mesh.nExteriorElementBoundaries_global - argsDict["exteriorElementBoundariesArray"] = self.mesh.exteriorElementBoundariesArray - argsDict["elementBoundaryElementsArray"] = self.mesh.elementBoundaryElementsArray - argsDict["elementBoundaryLocalElementBoundariesArray"] = self.mesh.elementBoundaryLocalElementBoundariesArray - argsDict["ebqe_velocity_ext"] = self.ebqe['velocity'] - argsDict["isDOFBoundary_u"] = self.numericalFlux.isDOFBoundary[0] - argsDict["ebqe_bc_u_ext"] = self.numericalFlux.ebqe[('u',0)] - argsDict["isFluxBoundary_u"] = self.ebqe[('advectiveFlux_bc_flag',0)] - argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] - argsDict["csrColumnOffsets_eb_u_u"] = self.csrColumnOffsets_eb[(0,0)] - argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX - self.calculateJacobian(argsDict) - if self.forceStrongConditions: - for dofN in list(self.dirichletConditionsForceDOF[0].DOFBoundaryConditionsDict.keys()): - global_dofN = self.offset[0]+self.stride[0]*dofN - self.nzval[np.where(self.colind == global_dofN)] = 0.0 #column - self.nzval[self.rowptr[global_dofN]:self.rowptr[global_dofN+1]] = 0.0 #row - zeroRow=True - for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]):#row - if (self.colind[i] == global_dofN): - self.nzval[i] = 1.0 - zeroRow = False - if zeroRow: - raise RuntimeError("Jacobian has a zero row because sparse matrix has no diagonal entry at row "+repr(global_dofN)+". You probably need add diagonal mass or reaction term") - #scaling = 1.0#probably want to add some scaling to match non-dirichlet diagonals in linear system - #for cj in range(self.nc): - # for dofN in list(self.dirichletConditionsForceDOF[cj].DOFBoundaryConditionsDict.keys()): - # global_dofN = self.offset[cj]+self.stride[cj]*dofN - # for i in range(self.rowptr[global_dofN],self.rowptr[global_dofN+1]): - # if (self.colind[i] == global_dofN): - # self.nzval[i] = scaling - # else: - # self.nzval[i] = 0.0 - logEvent("Jacobian ",level=10,data=jacobian) - #mwf decide if this is reasonable for solver statistics - self.nonlinear_function_jacobian_evaluations += 1 - return jacobian - def calculateElementQuadrature(self): - """ - Calculate the physical location and weights of the quadrature rules - and the shape information at the quadrature points. - - This function should be called only when the mesh changes. - """ - #self.u[0].femSpace.elementMaps.getValues(self.elementQuadraturePoints, - # self.q['x']) - self.u[0].femSpace.elementMaps.getBasisValuesRef(self.elementQuadraturePoints) - self.u[0].femSpace.elementMaps.getBasisGradientValuesRef(self.elementQuadraturePoints) - self.u[0].femSpace.getBasisValuesRef(self.elementQuadraturePoints) - self.u[0].femSpace.getBasisGradientValuesRef(self.elementQuadraturePoints) - self.coefficients.initializeElementQuadrature(self.timeIntegration.t,self.q) - if self.stabilization != None: - self.stabilization.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) - self.stabilization.initializeTimeIntegration(self.timeIntegration) - if self.shockCapturing != None: - self.shockCapturing.initializeElementQuadrature(self.mesh,self.timeIntegration.t,self.q) - def calculateElementBoundaryQuadrature(self): - pass - def calculateExteriorElementBoundaryQuadrature(self): - """ - Calculate the physical location and weights of the quadrature rules - and the shape information at the quadrature points on global element boundaries. - - This function should be called only when the mesh changes. - """ - # - #get physical locations of element boundary quadrature points - # - #assume all components live on the same mesh - self.u[0].femSpace.elementMaps.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.elementMaps.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.getBasisValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.getBasisGradientValuesTraceRef(self.elementBoundaryQuadraturePoints) - self.u[0].femSpace.elementMaps.getValuesGlobalExteriorTrace(self.elementBoundaryQuadraturePoints, - self.ebqe['x']) - self.fluxBoundaryConditionsObjectsDict = dict([(cj,FluxBoundaryConditions(self.mesh, - self.nElementBoundaryQuadraturePoints_elementBoundary, - self.ebqe[('x')], - getAdvectiveFluxBoundaryConditions=self.advectiveFluxBoundaryConditionsSetterDict[cj], - getDiffusiveFluxBoundaryConditions=self.diffusiveFluxBoundaryConditionsSetterDictDict[cj])) - for cj in list(self.advectiveFluxBoundaryConditionsSetterDict.keys())]) - self.coefficients.initializeGlobalExteriorElementBoundaryQuadrature(self.timeIntegration.t,self.ebqe) - def estimate_mt(self): - pass - def calculateSolutionAtQuadrature(self): - pass - def calculateAuxiliaryQuantitiesAfterStep(self): - pass From 2cd4e7f2bf7ce143a5b5ab637f597cd90472b257 Mon Sep 17 00:00:00 2001 From: abarua-ce Date: Thu, 18 Apr 2024 20:14:39 -0500 Subject: [PATCH 4/7] Added Richards.h and Richards.py from add_fct branch --- proteus/richards/Richards.h | 811 ++++++++++++++++------------------- proteus/richards/Richards.py | 49 +-- 2 files changed, 381 insertions(+), 479 deletions(-) diff --git a/proteus/richards/Richards.h b/proteus/richards/Richards.h index b1f54a2251..497ba6c03b 100644 --- a/proteus/richards/Richards.h +++ b/proteus/richards/Richards.h @@ -195,8 +195,8 @@ namespace proteus const double df[nSpace], const double a[nnz], const double da[nnz]) - { - register double psiC, + { + double psiC, pcBar,pcBar_n, sBar, thetaW, @@ -412,6 +412,47 @@ namespace proteus return anb_seepage_flux; } + double computeIthLimitedFluxCorrection( + int i, + const xt::pyarray& csrRowIndeces_DofLoops, + const xt::pyarray& csrColumnOffsets_DofLoops, + const xt::pyarray& uLow, + const xt::pyarray& dt_times_fH_minus_fL, + double dt, + double mi +) { + double Pposi = 0.0, Pnegi = 0.0; + double mini = 0.0, maxi = 1.0; + int ij = csrRowIndeces_DofLoops(i); // assuming using xtensor array + + for (int offset = csrRowIndeces_DofLoops(i); offset < csrRowIndeces_DofLoops(i + 1); ++offset) { + int j = csrColumnOffsets_DofLoops(offset); + // Compute P vectors + Pposi += dt_times_fH_minus_fL(offset) * (dt_times_fH_minus_fL(offset) > 0 ? 1.0 : 0.0); + Pnegi += dt_times_fH_minus_fL(offset) * (dt_times_fH_minus_fL(offset) < 0 ? 1.0 : 0.0); + } + + double Qposi = mi * (maxi - uLow(i)); + double Qnegi = mi * (mini - uLow(i)); + double Rposi = (Pposi == 0.0) ? 1.0 : std::fmin(1.0, Qposi / Pposi); + double Rnegi = (Pnegi == 0.0) ? 1.0 : std::fmin(1.0, Qnegi / Pnegi); + + double ith_limited_flux_correction = 0.0; + for (int offset = csrRowIndeces_DofLoops(i); offset < csrRowIndeces_DofLoops(i + 1); ++offset) { + int j = csrColumnOffsets_DofLoops(offset); + double Lij = dt_times_fH_minus_fL(offset) > 0 ? std::fmin(Rposi, uLow(j)) : std::fmin(Rnegi, uLow(j)); + ith_limited_flux_correction += Lij * dt_times_fH_minus_fL(offset); + } + + if (std::isnan(ith_limited_flux_correction)) { + ith_limited_flux_correction = 0.0; + } + + return ith_limited_flux_correction; +} + + + void calculateResidual(arguments_dict& args) { xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); @@ -554,7 +595,7 @@ namespace proteus for(int eN=0;eN& max_s_bc = args.array("max_s_bc"); int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); int MONOLITHIC = args.scalar("MONOLITHIC"); - register double Rpos[numDOFs], Rneg[numDOFs]; - register double FluxCorrectionMatrix[NNZ]; - register double solL[numDOFs]; - register double sdot[numDOFs]; + double Rpos[numDOFs], Rneg[numDOFs]; + double FluxCorrectionMatrix[NNZ]; + double solL[numDOFs]; + double sdot[numDOFs]; ////////////////// // LOOP in DOFs // ////////////////// @@ -1542,7 +1570,7 @@ namespace proteus xt::pyarray& max_s_bc = args.array("max_s_bc"); int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); int MONOLITHIC = args.scalar("MONOLITHIC"); - register double Rpos[numDOFs], Rneg[numDOFs]; + double Rpos[numDOFs], Rneg[numDOFs]; int ij=0; ////////////////////////////////////////////////////// @@ -1796,13 +1824,13 @@ namespace proteus anb_seepage_flux=0.0; - register double Rpos[numDOFs], Rneg[numDOFs]; - //register double FluxCorrectionMatrix[NNZ]; + double Rpos[numDOFs], Rneg[numDOFs]; + //double FluxCorrectionMatrix[NNZ]; // NOTE: This function follows a different (but equivalent) implementation of the smoothness based indicator than NCLS.h // Allocate space for the transport matrices // This is used for first order KUZMIN'S METHOD - register double TransportMatrix[NNZ],TransportMatrixConsistent[NNZ]; - register double TransportMatrixn[NNZ],TransportMatrixConsistentn[NNZ]; + double TransportMatrix[NNZ],TransportMatrixConsistent[NNZ]; + double TransportMatrixn[NNZ],TransportMatrixConsistentn[NNZ]; std::valarray u_free_dof(numDOFs); std::valarray u_free_dof_old(numDOFs); std::valarray ML2(numDOFs); @@ -1811,7 +1839,7 @@ namespace proteus for(int eN=0;eN0) - { - std::cout<<"The seepage flux is "<0) + // { + // std::cout<<"The seepage flux is "<("anb_seepage_flux_n"); - //anb_seepage_flux_n=0.0; + // //anb_seepage_flux += dS* flux_ext; + // //double anb_seepage_flux_n = args.scalar("anb_seepage_flux_n"); + // //anb_seepage_flux_n=0.0; - //anb_seepage_flux_n= anb_seepage_flux; + // //anb_seepage_flux_n= anb_seepage_flux; - //if (isSeepageFace) - //{ - // anb_seepage_flux+= dS* flux_ext; - // std::cout<<"The seepage flux is "<0){ - // std::cout<<"The seepage flux is "<0){ + // // std::cout<<"The seepage flux is "<= 0 && isFluxBoundary_u[ebNE_kb] != 1 ) //outflow. This is handled via the transport matrices. Then flux_ext=0 and dflux_ext!=0 - // { - // dflux_ext = flow; - // flux_ext = 0; - // // save external u - // ebqe_u[ebNE_kb] = u_ext; - // } - //else // inflow. This is handled via the boundary integral. Then flux_ext!=0 and dflux_ext=0 - //{ - //dflux_ext = 0; - // save external u - //ebqe_u[ebNE_kb] = isDOFBoundary_u[ebNE_kb]*ebqe_bc_u_ext[ebNE_kb]+(1-isDOFBoundary_u[ebNE_kb])*u_ext; - //if (isDOFBoundary_u[ebNE_kb] == 1) - // flux_ext = ebqe_bc_u_ext[ebNE_kb]*flow; - //else if (isFluxBoundary_u[ebNE_kb] == 1) - //flux_ext = ebqe_bc_flux_u_ext[ebNE_kb]; - // flux_ext = ebqe_bc_u_ext[ebNE_kb]; - //else - // { - // std::cout<<"warning: VOF open boundary with no external trace, setting to zero for inflow"<= 0 && isFluxBoundary_u[ebNE_kb] != 1 ) //outflow. This is handled via the transport matrices. Then flux_ext=0 and dflux_ext!=0 + // // { + // // dflux_ext = flow; + // // flux_ext = 0; + // // // save external u + // // ebqe_u[ebNE_kb] = u_ext; + // // } + // //else // inflow. This is handled via the boundary integral. Then flux_ext!=0 and dflux_ext=0 + // //{ + // //dflux_ext = 0; + // // save external u + // //ebqe_u[ebNE_kb] = isDOFBoundary_u[ebNE_kb]*ebqe_bc_u_ext[ebNE_kb]+(1-isDOFBoundary_u[ebNE_kb])*u_ext; + // //if (isDOFBoundary_u[ebNE_kb] == 1) + // // flux_ext = ebqe_bc_u_ext[ebNE_kb]*flow; + // //else if (isFluxBoundary_u[ebNE_kb] == 1) + // //flux_ext = ebqe_bc_flux_u_ext[ebNE_kb]; + // // flux_ext = ebqe_bc_u_ext[ebNE_kb]; + // //else + // // { + // // std::cout<<"warning: VOF open boundary with no external trace, setting to zero for inflow"<& bc_mask = args.array("bc_mask"); - //int NNZ = args.scalar("NNZ"); //number on non-zero entries on sparsity pattern - //int numDOFs = args.scalar("numDOFs"); //number of DOFs - //double dt = args.scalar("dt"); - //xt::pyarray& lumped_mass_matrix = args.array("lumped_mass_matrix"); //lumped mass matrix (as vector) - - xt::pyarray& soln = args.array("soln"); //DOFs of solution at time tn - //xt::pyarray& pn = args.array("pn"); //DOFs of solution at time tn - //xt::pyarray& solH = args.array("solH"); //DOFs of high order solution at tnp1 - //xt::pyarray& uLow = args.array("uLow"); - //xt::pyarray& uDotLow = args.array("uDotLow"); - //xt::pyarray& limited_solution = args.array("limited_solution"); - xt::pyarray& csrRowIndeces_DofLoops = args.array("csrRowIndeces_DofLoops"); //csr row indeces - xt::pyarray& csrColumnOffsets_DofLoops = args.array("csrColumnOffsets_DofLoops"); //csr column offsets - //xt::pyarray& MassMatrix = args.array("MassMatrix"); //mass matrix - //xt::pyarray& dt_times_fH_minus_fL = args.array("dt_times_fH_minus_fL"); //low minus high order dissipative matrices - //xt::pyarray& min_s_bc = args.array("min_s_bc"); //min/max value at BCs. If DOF is not at boundary then min=1E10, max=-1E10 - //xt::pyarray& max_s_bc = args.array("max_s_bc"); - //int LUMPED_MASS_MATRIX = args.scalar("LUMPED_MASS_MATRIX"); - //int MONOLITHIC = args.scalar("MONOLITHIC"); - register double Rpos[numDOFs], Rneg[numDOFs]; - register double FluxCorrectionMatrix[NNZ]; - xt::pyarray& solLim = args.array("limited_solution"); - //register double solL[numDOFs]; - //register double sdot[numDOFs]; - - ij=0; - for (int i=0; i 0 ? 1. : 0.); - Pnegi += fij * (fij < 0 ? 1. : 0.); - //update ij - ij+=1; - } - - // compute Q vectors // - double mi = ML.data()[i]; - double Qposi = mi*(maxi-solLim.data()[i]); - double Qnegi = mi*(mini-solLim.data()[i]); - // compute R vectors // - Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); - } - ij=0; - for (int i=0; i 0 ? fmin(Rposi,Rneg[j]) : fmin(Rnegi,Rpos[j]); - // compute ith_limited_flux_correction - ith_limited_flux_correction += Lij*fij; - ij+=1; - } - double mi = ML.data()[i]; - solLim[i] += 1./mi*ith_limited_flux_correction; - } - - //std::cout<<"Limiter "<< ith_Limiter_times_FluxCorrectionMatrix <& a_rowptr = args.array("a_rowptr"); @@ -3056,7 +2995,7 @@ namespace proteus // for(int eN=0;eNebN? ebN = mesh.exteriorElementBoundariesArray[ebNE] #print "eb flag",mesh.elementBoundaryMaterialTypes[ebN] - #print("Hi, Arnob") + #print self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) self.isSeepageFace[ebNE] = self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) #print (self.isSeepageFace) @@ -575,50 +575,31 @@ def __init__(self, if elemQuadIsDict: if ('numDiff',ci,ci) in elementQuadrature: elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature[('numDiff',ci,ci)] - #print("Hi, Arnob1") - #print(anb_seepage_flux) + else: elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature['default'] - #print("Hi, Arnob2") - #print(anb_seepage_flux) else: elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature - print("Hi, Arnob3") - #print(anb_seepage_flux) if massLumping: for ci in list(self.coefficients.mass.keys()): elementQuadratureDict[('m',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - print("Hi, Arnob4") - #print(anb_seepage_flux) for I in self.coefficients.elementIntegralKeys: elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - print("Hi, Arnob5") - #print(anb_seepage_flux) if reactionLumping: for ci in list(self.coefficients.mass.keys()): elementQuadratureDict[('r',ci)] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - print("Hi, Arnob6") - #print(anb_seepage_flux) for I in self.coefficients.elementIntegralKeys: elementQuadratureDict[('stab',)+I[1:]] = Quadrature.SimplexLobattoQuadrature(self.nSpace_global,1) - print("Hi, Arnob7") - #print(anb_seepage_flux) elementBoundaryQuadratureDict={} if isinstance(elementBoundaryQuadrature,dict): #set terms manually for I in self.coefficients.elementBoundaryIntegralKeys: if I in elementBoundaryQuadrature: elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature[I] - print("Hi, Arnob8") - #print(anb_seepage_flux) else: elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature['default'] - #print("Hi, Arnob9") - #print(anb_seepage_flux) else: for I in self.coefficients.elementBoundaryIntegralKeys: elementBoundaryQuadratureDict[I] = elementBoundaryQuadrature - print("Hi, Arnob10") - #print(anb_seepage_flux) # # find the union of all element quadrature points and # build a quadrature rule for each integral that has a @@ -1377,6 +1358,7 @@ def getResidual(self,u,r): else: self.calculateResidual = self.richards.calculateResidual_entropy_viscosity self.calculateJacobian = self.richards.calculateMassMatrix + if self.delta_x_ij is None: self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') self.calculateResidual(argsDict) @@ -1395,11 +1377,6 @@ def getResidual(self,u,r): if self.globalResidualDummy is None: self.globalResidualDummy = np.zeros(r.shape,'d') - #print("Hello from the python file", self.coefficients.anb_seepage_flux) - #logEvent("Hello from the python file", self.coefficients.anb_seepage_flux") - - - def invert(self,u,r): @@ -1556,8 +1533,7 @@ def invert(self,u,r): argsDict["sn"] = self.sn #Arnob trying to print flux argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - #print("Hi",anb_seepage_flux) - #print("Hi Seepage Flux", self.coefficients.anb_seepage_flux) + self.richards.invert(argsDict) # self.timeIntegration.dt, @@ -1762,19 +1738,6 @@ def getJacobian(self,jacobian): argsDict["csrColumnOffsets_eb_u_u"] = self.csrColumnOffsets_eb[(0,0)] argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - - #arnob trying to calculate flux - #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - #Arnob trying to print flux - #argsDict["anb_seepage_flux"] = self.calculateResidual.anb_seepage_flux - - #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux - #print("Hi Seepage Flux", self.coefficients.anb_seepage_flux) - #print("Hi Seepage Flux",anb_seepage_flux) - #print("The seepage is ", anb_seepage_flux) - - - self.calculateJacobian(argsDict) if self.forceStrongConditions: From 7cc91a8ea14e46299db353dcb9286d9fc7498fa7 Mon Sep 17 00:00:00 2001 From: abarua-ce Date: Thu, 25 Apr 2024 18:11:58 -0500 Subject: [PATCH 5/7] Added python file from add_fct branch --- proteus/richards/Richards.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/proteus/richards/Richards.py b/proteus/richards/Richards.py index c458dd7d8d..f800176923 100644 --- a/proteus/richards/Richards.py +++ b/proteus/richards/Richards.py @@ -739,12 +739,8 @@ def __init__(self, ################################################################# ####################ARNOB_FCT_EDIT############################### ################################################################# - - if self.coefficients.LUMPED_MASS_MATRIX == False: - cond = self.coefficients.STABILIZATION_TYPE == 2 - assert cond, "Use lumped mass matrix just with: STABILIZATION_TYPE=2 (smoothness based stab.)" + if not self.coefficients.LUMPED_MASS_MATRIX and self.coefficients.STABILIZATION_TYPE == 2: cond = 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == Newton - #assert cond, "Use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards when the mass matrix is lumped" From 4c0c1d5a05ee968653539599fd79717b1c1053dd Mon Sep 17 00:00:00 2001 From: Arnob Barua <35999938+abarua-ce@users.noreply.github.com> Date: Fri, 3 May 2024 15:18:15 -0500 Subject: [PATCH 6/7] Fct updates arnob (#5) first attempt at fixing the implicit fct version of richards --- proteus/richards/Richards.h | 712 ++++++++++++++++++++++++----------- proteus/richards/Richards.py | 113 +++++- 2 files changed, 595 insertions(+), 230 deletions(-) diff --git a/proteus/richards/Richards.h b/proteus/richards/Richards.h index 1adaaefeef..497ba6c03b 100644 --- a/proteus/richards/Richards.h +++ b/proteus/richards/Richards.h @@ -32,12 +32,15 @@ namespace proteus } namespace proteus + { class Richards_base { //The base class defining the interface public: - virtual ~Richards_base(){} + virtual ~Richards_base(){ + double anb_seepage_flux =1e-16; + } virtual void calculateResidual(arguments_dict& args)=0; virtual void calculateJacobian(arguments_dict& args)=0; virtual void invert(arguments_dict& args)=0; @@ -113,6 +116,7 @@ namespace proteus psiC = -u; m_vg = 1.0 - 1.0 / n_vg; thetaS = thetaR + thetaSR; + //std::cout<< "Thetas"< 0.0) { pcBar = alpha * psiC; @@ -172,7 +176,7 @@ namespace proteus } } } - + inline void evaluateInverseCoefficients(const int rowptr[nSpace], const int colind[nnz], @@ -183,7 +187,7 @@ namespace proteus const double n_vg, const double thetaR, const double thetaSR, - const double KWs[nnz], + const double KWs[nnz], double& u, const double& m, const double& dm, @@ -191,7 +195,7 @@ namespace proteus const double df[nSpace], const double a[nnz], const double da[nnz]) - { + { double psiC, pcBar,pcBar_n, sBar, @@ -222,7 +226,6 @@ namespace proteus <<"psiC "<& csrRowIndeces_DofLoops, + const xt::pyarray& csrColumnOffsets_DofLoops, + const xt::pyarray& uLow, + const xt::pyarray& dt_times_fH_minus_fL, + double dt, + double mi +) { + double Pposi = 0.0, Pnegi = 0.0; + double mini = 0.0, maxi = 1.0; + int ij = csrRowIndeces_DofLoops(i); // assuming using xtensor array + + for (int offset = csrRowIndeces_DofLoops(i); offset < csrRowIndeces_DofLoops(i + 1); ++offset) { + int j = csrColumnOffsets_DofLoops(offset); + // Compute P vectors + Pposi += dt_times_fH_minus_fL(offset) * (dt_times_fH_minus_fL(offset) > 0 ? 1.0 : 0.0); + Pnegi += dt_times_fH_minus_fL(offset) * (dt_times_fH_minus_fL(offset) < 0 ? 1.0 : 0.0); + } + + double Qposi = mi * (maxi - uLow(i)); + double Qnegi = mi * (mini - uLow(i)); + double Rposi = (Pposi == 0.0) ? 1.0 : std::fmin(1.0, Qposi / Pposi); + double Rnegi = (Pnegi == 0.0) ? 1.0 : std::fmin(1.0, Qnegi / Pnegi); + + double ith_limited_flux_correction = 0.0; + for (int offset = csrRowIndeces_DofLoops(i); offset < csrRowIndeces_DofLoops(i + 1); ++offset) { + int j = csrColumnOffsets_DofLoops(offset); + double Lij = dt_times_fH_minus_fL(offset) > 0 ? std::fmin(Rposi, uLow(j)) : std::fmin(Rnegi, uLow(j)); + ith_limited_flux_correction += Lij * dt_times_fH_minus_fL(offset); + } + + if (std::isnan(ith_limited_flux_correction)) { + ith_limited_flux_correction = 0.0; + } + + return ith_limited_flux_correction; +} + + + void calculateResidual(arguments_dict& args) { xt::pyarray& mesh_trial_ref = args.array("mesh_trial_ref"); @@ -501,11 +562,26 @@ namespace proteus xt::pyarray& quantDOFs = args.array("quantDOFs"); xt::pyarray& sLow = args.array("sLow"); xt::pyarray& sn = args.array("sn"); - + assert(a_rowptr.data()[nSpace] == nnz); assert(a_rowptr.data()[nSpace] == nSpace); //cek should this be read in? double Ct_sge = 4.0; + //For flux Calculation + //double anb_seepage_flux=0.0; + //anb_seepage_flux = args["anb_seepage_flux"]; + //double anb_seepage_flux = args.scalar("anb_seepage_flux"); + //anb_seepage_flux=0.0; + + xt::pyarray& anb_seepage_flux_n = args.array("anb_seepage_flux_n"); + + + //double anb_seepage_flux=0.0; + double & anb_seepage_flux (args.scalar("anb_seepage_flux")) ; + //double anb_seepage_flux = args.scalar("anb_seepage_flux_n"); + + //double anb_seepage_flux=0.0; + anb_seepage_flux=0.0; //loop over elements to compute volume integrals and load them into element and global residual // @@ -648,8 +724,6 @@ namespace proteus /* // */ /* //calculate shock capturing diffusion */ /* // */ - - /* ck.calculateNumericalDiffusion(shockCapturingDiffusion,elementDiameter[eN],pdeResidual_u,grad_u,numDiff0); */ /* //ck.calculateNumericalDiffusion(shockCapturingDiffusion,G,pdeResidual_u,grad_u_old,numDiff1); */ /* ck.calculateNumericalDiffusion(shockCapturingDiffusion,sc_uref, sc_alpha,G,G_dd_G,pdeResidual_u,grad_u,numDiff1); */ @@ -718,6 +792,7 @@ namespace proteus da_ext[nnz], as_ext[nnz], flux_ext=0.0, + //anb_seepage_flux=0.0, // for flux calculation bc_u_ext=0.0, bc_grad_u_ext[nSpace], bc_m_ext=0.0, @@ -852,17 +927,32 @@ namespace proteus ebqe_penalty_ext.data()[ebNE_kb],// penalty, flux_ext); ebqe_flux.data()[ebNE_kb] = flux_ext; - ebqe_u.data()[ebNE_kb] = u_ext; + + anb_seepage_flux= seepagefluxcalculator(anb_seepage_flux, + isSeepageFace.data()[ebNE], + dS, + flux_ext); + //std::cout<<"The seepage flux is "<0) + { + std::cout<<"The seepage flux is "<0 ? Rposi : Rpos[j]); + Lij = (Fluxij>0 ? Rposi : Rpos[j]); // compute limited flux ith_Limiter_times_FluxCorrectionMatrix += Lij*Fluxij; - + // update limited flux limitedFlux.data()[ij] = Lij*Fluxij; - + //update FluxMatrix - FluxMatrix.data()[ij] = Fluxij; - + FluxMatrix.data()[ij] = Fluxij; + //update ij ij+=1; } @@ -1575,7 +1669,7 @@ namespace proteus double Qnegi = mi*(mini-solLim.data()[i]); // compute R vectors // Rpos[i] = ((Pposi==0) ? 1. : fmin(1.0,Qposi/Pposi)); - Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); + Rneg[i] = ((Pnegi==0) ? 1. : fmin(1.0,Qnegi/Pnegi)); } // COMPUTE LIMITERS // @@ -1623,6 +1717,7 @@ namespace proteus xt::pyarray& mesh_grad_trial_trace_ref = args.array("mesh_grad_trial_trace_ref"); xt::pyarray& dS_ref = args.array("dS_ref"); xt::pyarray& u_trial_trace_ref = args.array("u_trial_trace_ref"); + xt::pyarray& u_grad_trial_trace_ref = args.array("u_grad_trial_trace_ref"); xt::pyarray& u_test_trace_ref = args.array("u_test_trace_ref"); xt::pyarray& u_grad_test_trace_ref = args.array("u_grad_test_trace_ref"); @@ -1717,6 +1812,18 @@ namespace proteus xt::pyarray& quantDOFs = args.array("quantDOFs"); xt::pyarray& sLow = args.array("sLow"); xt::pyarray& sn = args.array("sn"); + + xt::pyarray& anb_seepage_flux_n = args.array("anb_seepage_flux_n"); + + + //double anb_seepage_flux=0.0; + double & anb_seepage_flux (args.scalar("anb_seepage_flux")) ; + //double anb_seepage_flux = args.scalar("anb_seepage_flux_n"); + + //double anb_seepage_flux=0.0; + anb_seepage_flux=0.0; + + double Rpos[numDOFs], Rneg[numDOFs]; //double FluxCorrectionMatrix[NNZ]; // NOTE: This function follows a different (but equivalent) implementation of the smoothness based indicator than NCLS.h @@ -1727,6 +1834,8 @@ namespace proteus std::valarray u_free_dof(numDOFs); std::valarray u_free_dof_old(numDOFs); std::valarray ML2(numDOFs); + + for(int eN=0;eN= 0 && isFluxBoundary_u[ebNE_kb] != 1 ) //outflow. This is handled via the transport matrices. Then flux_ext=0 and dflux_ext!=0 */ - /* { */ - /* dflux_ext = flow; */ - /* flux_ext = 0; */ - /* // save external u */ - /* ebqe_u[ebNE_kb] = u_ext; */ - /* } */ - /* else // inflow. This is handled via the boundary integral. Then flux_ext!=0 and dflux_ext=0 */ - /* { */ - /* dflux_ext = 0; */ - /* // save external u */ - /* ebqe_u[ebNE_kb] = isDOFBoundary_u[ebNE_kb]*ebqe_bc_u_ext[ebNE_kb]+(1-isDOFBoundary_u[ebNE_kb])*u_ext; */ - /* if (isDOFBoundary_u[ebNE_kb] == 1) */ - /* flux_ext = ebqe_bc_u_ext[ebNE_kb]*flow; */ - /* else if (isFluxBoundary_u[ebNE_kb] == 1) */ - /* flux_ext = ebqe_bc_flux_u_ext[ebNE_kb]; */ - /* else */ - /* { */ - /* std::cout<<"warning: VOF open boundary with no external trace, setting to zero for inflow"<0) + // { + // std::cout<<"The seepage flux is "<("anb_seepage_flux_n"); + // //anb_seepage_flux_n=0.0; + + // //anb_seepage_flux_n= anb_seepage_flux; + + + + // //if (isSeepageFace) + // //{ + // // anb_seepage_flux+= dS* flux_ext; + // // std::cout<<"The seepage flux is "<0){ + // // std::cout<<"The seepage flux is "<= 0 && isFluxBoundary_u[ebNE_kb] != 1 ) //outflow. This is handled via the transport matrices. Then flux_ext=0 and dflux_ext!=0 + // // { + // // dflux_ext = flow; + // // flux_ext = 0; + // // // save external u + // // ebqe_u[ebNE_kb] = u_ext; + // // } + // //else // inflow. This is handled via the boundary integral. Then flux_ext!=0 and dflux_ext=0 + // //{ + // //dflux_ext = 0; + // // save external u + // //ebqe_u[ebNE_kb] = isDOFBoundary_u[ebNE_kb]*ebqe_bc_u_ext[ebNE_kb]+(1-isDOFBoundary_u[ebNE_kb])*u_ext; + // //if (isDOFBoundary_u[ebNE_kb] == 1) + // // flux_ext = ebqe_bc_u_ext[ebNE_kb]*flow; + // //else if (isFluxBoundary_u[ebNE_kb] == 1) + // //flux_ext = ebqe_bc_flux_u_ext[ebNE_kb]; + // // flux_ext = ebqe_bc_u_ext[ebNE_kb]; + // //else + // // { + // // std::cout<<"warning: VOF open boundary with no external trace, setting to zero for inflow"< mMax) - { - std::cout<<"mass out of bounds "< mMax) + { + std::cout<<"mass out of bounds "< 1.0 || Rposi < 0.0) + //if (Rposi > 1.0 || Rposi < 0.0) //std::cout << "Rposi: " << Rposi << std::endl; - //if (Rnegi > 1.0 || Rnegi < 0.0) - //std::cout << "Rnegi: " << Rnegi << std::endl; - + //if (Rnegi > 1.0 || Rnegi < 0.0) + //std::cout << "Rnegi: " << Rnegi << std::endl; + // LOOP OVER THE SPARSITY PATTERN (j-LOOP)// // for (int offset=csrRowIndeces_DofLoops.data()[i]; // offset& a_rowptr = args.array("a_rowptr"); @@ -2926,6 +3202,8 @@ namespace proteus }//computeMassMatrix };//Richards + + inline Richards_base* newRichards(int nSpaceIn, int nQuadraturePoints_elementIn, int nDOF_mesh_trial_elementIn, @@ -2936,11 +3214,11 @@ namespace proteus { if (nSpaceIn == 1) return proteus::chooseAndAllocateDiscretization1D(nSpaceIn, - nQuadraturePoints_elementIn, - nDOF_mesh_trial_elementIn, - nDOF_trial_elementIn, - nDOF_test_elementIn, - nQuadraturePoints_elementBoundaryIn, + nQuadraturePoints_elementIn, + nDOF_mesh_trial_elementIn, + nDOF_trial_elementIn, + nDOF_test_elementIn, + nQuadraturePoints_elementBoundaryIn, CompKernelFlag); else if (nSpaceIn == 2) return proteus::chooseAndAllocateDiscretization2D(nSpaceIn, @@ -2962,5 +3240,5 @@ namespace proteus CompKernelFlag); } } -}//proteus -#endif +};//proteus +#endif \ No newline at end of file diff --git a/proteus/richards/Richards.py b/proteus/richards/Richards.py index 841fcd0884..f800176923 100644 --- a/proteus/richards/Richards.py +++ b/proteus/richards/Richards.py @@ -12,6 +12,8 @@ from proteus.LinearAlgebraTools import SparseMat from proteus import TimeIntegration from proteus.NonlinearSolvers import ExplicitLumpedMassMatrixForRichards +from proteus.NonlinearSolvers import Newton + class ThetaScheme(TimeIntegration.BackwardEuler): def __init__(self,transport,integrateInterpolationPoints=False): @@ -51,6 +53,8 @@ def __init__(self, transport, timeOrder=1, runCFL=0.1, integrateInterpolationPoi self.u_dof_stage[ci] = [] for k in range(self.nStages + 1): self.u_dof_stage[ci].append(transport.u[ci].dof.copy()) + #print() + # def set_dt(self, DTSET): # self.dt = DTSET # don't update t @@ -63,6 +67,8 @@ def choose_dt(self): self.dtLast = self.dt self.t = self.tLast + self.dt self.substeps = [self.t for i in range(self.nStages)] # Manuel is ignoring different time step levels for now + + def initialize_dt(self, t0, tOut, q): """ @@ -134,6 +140,7 @@ def updateStage(self): for ci in range(self.nc): self.u_dof_stage[ci][self.lstage][:] = self.transport.u[ci].dof[:] self.transport.u_dof_old[:] = self.transport.u[ci].dof + def initializeTimeHistory(self, resetFromDOF=True): """ @@ -199,6 +206,8 @@ def setFromOptions(self, nOptions): setattr(self, flag, val) if flag == 'timeOrder': self.resetOrder(self.timeOrder) + + class Coefficients(proteus.TransportCoefficients.TC_base): """ @@ -223,8 +232,7 @@ def __init__(self, ENTROPY_TYPE=2, # logarithmic LUMPED_MASS_MATRIX=False, MONOLITHIC=True, - FCT=False, - forceStrongBoundaryConditions=False, + FCT=True, num_fct_iter=1, # FOR ENTROPY VISCOSITY cE=1.0, @@ -233,7 +241,9 @@ def __init__(self, # FOR ARTIFICIAL COMPRESSION cK=1.0, # OUTPUT quantDOFs - outputQuantDOFs=False): + outputQuantDOFs=False, ): + self.anb_seepage_flux= 0.00 + #self.anb_seepage_flux_n =0.0 variableNames=['pressure_head'] nc=1 mass={0:{0:'nonlinear'}} @@ -294,7 +304,7 @@ def __init__(self, self.uL = uL self.uR = uR self.cK = cK - self.forceStrongConditions = forceStrongBoundaryConditions + self.forceStrongConditions = True self.cE = cE self.outputQuantDOFs = outputQuantDOFs TC_base.__init__(self, @@ -320,12 +330,15 @@ def initializeMesh(self,mesh): #mwf missing ebNE-->ebN? ebN = mesh.exteriorElementBoundariesArray[ebNE] #print "eb flag",mesh.elementBoundaryMaterialTypes[ebN] + #print self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) self.isSeepageFace[ebNE] = self.getSeepageFace(mesh.elementBoundaryMaterialTypes[ebN]) - #print self.isSeepageFace + #print (self.isSeepageFace) def initializeElementQuadrature(self,t,cq): self.materialTypes_q = self.elementMaterialTypes self.q_shape = cq[('u',0)].shape + #self.anb_seepage_flux= anb_seepage_flux + #print("The seepage is ", anb_seepage_flux) # cq['Ks'] = np.zeros(self.q_shape,'d') # for k in range(self.q_shape[1]): # cq['Ks'][:,k] = self.Ksw_types[self.elementMaterialTypes,0] @@ -342,6 +355,8 @@ def initializeGlobalExteriorElementBoundaryQuadrature(self,t,cebqe): self.ebqe_shape = cebqe[('u',0)].shape self.ebqe[('vol_frac',0)] = np.zeros(self.ebqe_shape,'d') # + + def evaluate(self,t,c): if c[('u',0)].shape == self.q_shape: materialTypes = self.materialTypes_q @@ -402,11 +417,13 @@ def evaluate(self,t,c): np.isnan(c[('dm',0,0)]).any()): import pdb pdb.set_trace() - -# #mwf debug -# if c[('u',0)].shape == self.q_shape: -# c[('visPerm',0)]=c[('a',0,0)][:,:,0,0] - + + def postStep(self, t, firstStep=False): + # #anb_seepage_flux_n[:]= self.anb_seepage_flux + with open('seepage_stab_0', "a") as f: + # f.write("\n Time"+ ",\t" +"Seepage\n") + f.write(repr(t)+ ",\t")# +repr(np.sum(self.LevelModel.anb_seepage_flux_n))) + class LevelModel(proteus.Transport.OneLevelTransport): nCalls=0 def __init__(self, @@ -538,6 +555,7 @@ def __init__(self, for I in self.coefficients.elementIntegralKeys: if I in elementQuadrature: elementQuadratureDict[I] = elementQuadrature[I] + else: elementQuadratureDict[I] = elementQuadrature['default'] else: @@ -557,6 +575,7 @@ def __init__(self, if elemQuadIsDict: if ('numDiff',ci,ci) in elementQuadrature: elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature[('numDiff',ci,ci)] + else: elementQuadratureDict[('numDiff',ci,ci)] = elementQuadrature['default'] else: @@ -716,6 +735,17 @@ def __init__(self, assert cond, "Use lumped mass matrix just with: STABILIZATION_TYPE=2 (smoothness based stab.)" cond = 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == ExplicitLumpedMassMatrixForRichards assert cond, "Use levelNonlinearSolver=ExplicitLumpedMassMatrixForRichards when the mass matrix is lumped" + + ################################################################# + ####################ARNOB_FCT_EDIT############################### + ################################################################# + if not self.coefficients.LUMPED_MASS_MATRIX and self.coefficients.STABILIZATION_TYPE == 2: + cond = 'levelNonlinearSolver' in dir(options) and options.levelNonlinearSolver == Newton + + + + + if self.coefficients.FCT == True: cond = self.coefficients.STABILIZATION_TYPE > 0, "Use FCT just with STABILIZATION_TYPE>0; i.e., edge based stabilization" # END OF ASSERTS @@ -739,6 +769,7 @@ def __init__(self, self.sLow = np.zeros(self.u[0].dof.shape, 'd') self.sHigh = np.zeros(self.u[0].dof.shape, 'd') self.sn = np.zeros(self.u[0].dof.shape, 'd') + self.anb_seepage_flux_n = np.zeros(self.u[0].dof.shape, 'd') comm = Comm.get() self.comm=comm if comm.size() > 1: @@ -749,6 +780,8 @@ def __init__(self, self.stride = [self.nc for ci in range(self.nc)] # logEvent(memory("stride+offset","OneLevelTransport"),level=4) + + if numericalFluxType != None: if options is None or options.periodicDirichletConditions is None: self.numericalFlux = numericalFluxType(self, @@ -821,7 +854,7 @@ def __init__(self, self.MOVING_DOMAIN=0.0 if self.mesh.nodeVelocityArray is None: self.mesh.nodeVelocityArray = np.zeros(self.mesh.nodeArray.shape,'d') - self.forceStrongConditions=self.coefficients.forceStrongConditions + self.forceStrongConditions=True self.dirichletConditionsForceDOF = {} if self.forceStrongConditions: for cj in range(self.nc): @@ -860,6 +893,7 @@ def FCTStep(self): argsDict["max_s_bc"] = np.ones_like(self.min_s_bc)*self.coefficients.rho*(self.coefficients.thetaR_types[0] + self.coefficients.thetaSR_types[0]) #cek hack argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX argsDict["MONOLITHIC"] =0#cek hack self.coefficients.MONOLITHIC + argsDict["anb_seepage_flux_n"]= self.anb_seepage_flux_n #pdb.set_trace() self.richards.FCTStep(argsDict) @@ -1177,8 +1211,7 @@ def getResidual(self,u,r): pass argsDict = cArgumentsDict.ArgumentsDict() - if self.forceStrongConditions: - argsDict["bc_mask"] = self.bc_mask + argsDict["bc_mask"] = self.bc_mask argsDict["dt"] = self.timeIntegration.dt argsDict["Theta"] = 1.0 argsDict["mesh_trial_ref"] = self.u[0].femSpace.elementMaps.psi @@ -1292,12 +1325,36 @@ def getResidual(self,u,r): argsDict["quantDOFs"] = self.quantDOFs argsDict["sLow"] = self.sLow argsDict["sn"] = self.sn + argsDict["anb_seepage_flux_n"]= self.anb_seepage_flux_n +###################################################################################### + argsDict["pn"] = self.u[0].dof + argsDict["solH"] = self.sHigh + + rowptr, colind, MassMatrix = self.MC_global.getCSRrepresentation() + argsDict["MassMatrix"] = MassMatrix + argsDict["solH"] = self.sHigh + +###################################################################################### + argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #print(anb_seepage_flux) + #argsDict["anb_seepage_flux_n"] = self.coefficients.anb_seepage_flux_n + #if np.sum(anb_seepage_flux_n)>0: + + #logEvent("Hi, this is Arnob", self.anb_seepage_flux_n[0]) + print("Seepage Flux from Python file", np.sum(self.anb_seepage_flux_n)) + seepage_text_variable= np.sum(self.anb_seepage_flux_n) + + with open('seepage_stab_0',"a" ) as f: + #f.write("\n Time"+ ",\t" +"Seepage\n") + #f.write(repr(self.coefficients.t)+ ",\t" +repr(seepage_text_variable), "\n") + f.write(repr(seepage_text_variable)+ "\n") if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG self.calculateResidual = self.richards.calculateResidual self.calculateJacobian = self.richards.calculateJacobian else: self.calculateResidual = self.richards.calculateResidual_entropy_viscosity self.calculateJacobian = self.richards.calculateMassMatrix + if self.delta_x_ij is None: self.delta_x_ij = -np.ones((self.nNonzerosInJacobian*3,),'d') self.calculateResidual(argsDict) @@ -1316,6 +1373,8 @@ def getResidual(self,u,r): if self.globalResidualDummy is None: self.globalResidualDummy = np.zeros(r.shape,'d') + + def invert(self,u,r): #u=s #r=p @@ -1468,6 +1527,10 @@ def invert(self,u,r): argsDict["quantDOFs"] = self.quantDOFs argsDict["sLow"] = self.sLow argsDict["sn"] = self.sn + #Arnob trying to print flux + argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + + self.richards.invert(argsDict) # self.timeIntegration.dt, # self.u[0].femSpace.elementMaps.psi, @@ -1591,6 +1654,10 @@ def invert(self,u,r): #self.nonlinear_function_evaluations += 1 #if self.globalResidualDummy is None: # self.globalResidualDummy = numpy.zeros(r.shape,'d') + def postStep(self, t, firstStep=False): + with open('seepage_flux_nnnn', "a") as f: + f.write("\n Time"+ ",\t" +"Seepage\n") + f.write(repr(t)+ ",\t" +repr(self.coefficients.anb_seepage_flux)) def getJacobian(self,jacobian): if (self.coefficients.STABILIZATION_TYPE == 0): # SUPG cfemIntegrals.zeroJacobian_CSR(self.nNonzerosInJacobian, @@ -1666,6 +1733,8 @@ def getJacobian(self,jacobian): argsDict["ebqe_bc_flux_ext"] = self.ebqe[('advectiveFlux_bc',0)] argsDict["csrColumnOffsets_eb_u_u"] = self.csrColumnOffsets_eb[(0,0)] argsDict["LUMPED_MASS_MATRIX"] = self.coefficients.LUMPED_MASS_MATRIX + argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + self.calculateJacobian(argsDict) if self.forceStrongConditions: for dofN in list(self.dirichletConditionsForceDOF[0].DOFBoundaryConditionsDict.keys()): @@ -1737,9 +1806,27 @@ def calculateExteriorElementBoundaryQuadrature(self): getDiffusiveFluxBoundaryConditions=self.diffusiveFluxBoundaryConditionsSetterDictDict[cj])) for cj in list(self.advectiveFluxBoundaryConditionsSetterDict.keys())]) self.coefficients.initializeGlobalExteriorElementBoundaryQuadrature(self.timeIntegration.t,self.ebqe) + #argsDict = cArgumentsDict.ArgumentsDict() + #argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux + #print("Hi", self.coefficients.anb_seepage_flux) + + #print("The seepage is ", anb_seepage_flux) def estimate_mt(self): pass def calculateSolutionAtQuadrature(self): pass def calculateAuxiliaryQuantitiesAfterStep(self): pass + def postStep(self, t, firstStep=False): + with open('seepage_flux_nnnnk', "a") as f: + f.write("\n Time"+ ",\t" +"Seepage\n") + f.write(repr(t)+ ",\t" +repr(self.coefficients.anb_seepage_flux)) + + + +#argsDict["anb_seepage_flux"] = self.coefficients.anb_seepage_flux +#anb_seepage_flux= self.coefficients.anb_seepage_flux +#print("Hi",anb_seepage_flux) + + +#print("Hello from the python file", self.coefficients.anb_seepage_flux) From 2b45b9e38c841db5297b9656c11f64790cbfc841 Mon Sep 17 00:00:00 2001 From: abarua-ce Date: Tue, 14 May 2024 11:26:55 -0500 Subject: [PATCH 7/7] Python file without Seepage Flux print --- proteus/richards/Richards.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proteus/richards/Richards.py b/proteus/richards/Richards.py index f800176923..0cdd506784 100644 --- a/proteus/richards/Richards.py +++ b/proteus/richards/Richards.py @@ -1341,7 +1341,7 @@ def getResidual(self,u,r): #if np.sum(anb_seepage_flux_n)>0: #logEvent("Hi, this is Arnob", self.anb_seepage_flux_n[0]) - print("Seepage Flux from Python file", np.sum(self.anb_seepage_flux_n)) + #print("Seepage Flux from Python file", np.sum(self.anb_seepage_flux_n)) seepage_text_variable= np.sum(self.anb_seepage_flux_n) with open('seepage_stab_0',"a" ) as f: