Optimizing C++:

https://secure.wikimedia.org/wikibooks/en/wiki/Optimizing_C%2B%2B

Performance improving features:

https://secure.wikimedia.org/wikibooks/en/wiki/Optimizing_C%2B%2B/Writing_efficient_code/Performance_improving_features

Performance worsening features:

https://secure.wikimedia.org/wikibooks/en/wiki/Optimizing_C%2B%2B/Writing_efficient_code/Performance_worsening_features

Forum category: CSMP++ / C++ questions

Forum thread: Optimizing C++ Code ]]>

"Embedded software often runs on processors with limited computation power, thus optimizing the code becomes a necessity. In this article we will explore the following optimization techniques for C and C++ code developed for Real-time and Embedded Systems."

http://www.eventhelix.com/realtimemantra/basics/optimizingcandcppcode.htm

Robert

Forum category: CSMP++ / C++ questions

Forum thread: Optimizing C++ Code ]]>

have you had a look in to Moeck et al (2009)?

It gives you a slip tendency T_{s} along the lines of what I am dealing with in CO2 sequestration. The slip tendency is the ratio of the resolved shear to resolved normal stress on the fault surface which has to exceed the frictional sliding resistance (given by the sliding friction coefficient \mu_{s}).

So what you want is to compute the traction vector (which is the force acting on a surface element whereas stress acts on the volume element) for given stress tensor field on each single element in CSMP which represents the fault. Given the traction vector, you can resolve the shear and normal component on the element and compare it against the failure criterion as outlined in Pollard and Fletcher (2005). Maybe it is not necessarly to use the traction vector to compute the normal and shear component and use the farfield stress tensor field directly.

Stephan used this approach for calculation on stress dependent permeability changes for a fracture network using Cruikshank et al (1991). However, the stress field is held constant and does not include fluid pressure coupling.

I am not sure whether a stress redistribution calculation is possible without including displacement. Haven't seen any mehtods on this so far, but will have a thorough look into this. A reference as a starting point would be helpful, you have one?

Cheers,

Robert

Reference

- Moeck, Inga, Grzegorz Kwiatek, and Günter Zimmermann. 2009. Slip tendency analysis, fault reactivation potential and induced seismicity in a deep geothermal reservoir. Journal of Structural Geology 31, no. 10 (October): 1174-1182. doi:10.1016/j.jsg.2009.06.012.
- Pollard, David D., and Raymond C. Fletcher. 2005. Fundamentals of structural geology. Cambridge University Press.
- Cruikshank, Kenneth M., Guozhu Zhao, and Arvid M. Johnson. 1991. Analysis of minor fractures associated with joints and faulted joints. Journal of Structural Geology 13, no. 8: 865-886. doi:10.1016/0191-8141(91)90083-U.

Forum category: Miscellaneous / General discussion zone

Forum thread: Simple fault mechanics in CSMP ]]>

Here is the volume flux for one of Mandefro's Bristol meshes (with 3 orders permeability difference between fractures and matrix)

and the essentially zero divergence field

So, all seems well for triangular meshes and the new FV scheme but not necessarily quadrilateral meshes and the old scheme.

Forum category: CSMP++ / CSMP++ bugs (detected and/or fixed)

Forum thread: Divergence free velocity fields ]]>

Forum category: CSMP++ / CSMP++ bugs (detected and/or fixed)

Forum thread: Divergence free velocity fields ]]>

One thing that I want to address here is the divergence of velocity is equal to the total volume sink/source per volume per time, and it is equal to zero when you don't have sink or source in the domain, which I think it hasn't been considered in CSMP.

I have my own patch class which is my given name for the control volume in my new scheme and I have computed the flux balance over a patch and the divergence is in the range of numerical precision (epsilon) for triangular elements when you don't have a crazy permeability variation (like 1e-14 for matrix and 1e-8 for fracture). But for quadrilateral elements I have problem, and it comes from the pressure solution and it seems that the solver has not converged properly. I think if we tighten the convergence criteria for the solver the flux mismatch will vanish for the quadrilateral as well.

I never agree with adding or removing any mass to the CVs, and in my scheme I never do that and it is fine and I don't have any problem and it is conservative. I think there is something fishy with generic node center finite volume transport class. I propose to check it for a single phase case to find out if the problem is because of the mobilities that has been used in the transport algorithm or it comes from somewhere else.

Forum category: CSMP++ / CSMP++ bugs (detected and/or fixed)

Forum thread: Divergence free velocity fields ]]>

\begin{align} \nabla\cdot\mathbf{v}=0 \end{align}

or

(2)\begin{align} \nabla\cdot\left(\frac{k}{\mu}\nabla p\right)=0 \end{align}

and the resulting divergence, as computed with the FV scheme (Stephan's generic and my old one) must be numerically zero (this is the case for triangular meshes, see below). Now, I only get this for a homogeneous permeability field and quadrilateral finite elements, as shown in this image:

If I include a low-permeability region in the centre such that flow is around it, then the divergence becomes immediately non-zero.

Has somebody noticed this and/or a good explanation? We only realised this problem when Christine's Newton iterator got stuck trying to resolve these local source/sink terms that arise from the divergence.

Forum category: CSMP++ / CSMP++ bugs (detected and/or fixed)

Forum thread: Divergence free velocity fields ]]>

Reason is that in geothermal reservoir stimulation models such things have been used and we wondered if we could include them as well.

Forum category: Miscellaneous / General discussion zone

Forum thread: Simple fault mechanics in CSMP ]]>

So, valid Triangle output is not automatically valid CSMP-input all the time, but as you said, small changes do the trick.

Forum category: CSMP++ / Questions and tricks related to the source code

Forum thread: How to create a proper TRIANGLE-mesh? ]]>

Forum category: CSMP++ / Questions and tricks related to the source code

Forum thread: How to create a proper TRIANGLE-mesh? ]]>

The error is:

main: Enter name of 'Triangle' input file set: tetraMesh.1

MeshInterface::CheckTriangleOutput: '.ele' file contains no element attributes…

MeshInterface::CheckTriangleOutput 'tetraMesh.1' Input fileset apparently contains:

99013 nodes, 296148 segments=faces, 197136 triangles.

MeshInterface::ReadNodeDataFile: file 'tetraMesh.1.node' read successfully…

MeshInterface::ReadElementDataFile: file 'tetraMesh.1.ele' read successfully…

MeshInterface::ReadNeighborDataFile: file 'tetraMesh.1.neigh' read successfully…

csp5: ../CSP5.0/source_code/interfaces/CSP_TRIANGLE_Interface.cpp:936: void csp::TRIANGLE_Interface::FlagBoundaryNodesAccordingTo(csp::stl_index, csp::int32, const std::vector<unsigned int, std::allocator<unsigned int> >&, std::map<unsigned int, int, std::less<unsigned int>, std::allocator<std::pair<const unsigned int, int> > >&): Assertion ‘bit != bflags.end()’ failed.

Aborted

Is there a guideline on how to create a proper triangle-mesh?

Thanks,

Matthias

Forum category: CSMP++ / Questions and tricks related to the source code

Forum thread: How to create a proper TRIANGLE-mesh? ]]>

v=-k/mu*(grad(p)+ro*g*grad(z))

according to the picture above,

grad(z)=cos(alpha)

so, the velocity due to gravity force is -k/mu*ro*g*cos(alpha). This is the velocity along the line from gravitational force. To calculate the each component of velocity (in x and y directions), you should multiply the unit vector that connects points p1 and p2 by this value. If you add this velocity to the velocity due to pressure gradient then you have your total velocity for your lower dimensional element.

Forum category: CSMP++ / CSMP++ bugs (detected and/or fixed)

Forum thread: Bug in 1D line elements ]]>

Consider the following situation

Where the red vector is the velocity within a 1D fracture that has the same orientation. The fracture is represented as a 1D line element with starting point $P1$ (at location x1, y1 and hydrostatic pressure $\pi1$) and endpoint $P2$ (at location x2, y2 with hydrostatic pressure $\pi2$). For simplicity assume that permeability and viscosity are one and only a single phase fluid is present, which is at perfect hydrostatic equilibrium such that no fluid moves up or down and $\partial p/\partial z = \rho g$.

Now, because the fracture is oriented at some angle $\alpha$ to the vertical gravity vector $\mathbf{g}$, there will be a pressure gradient in the x and z direction, causing an "apparent velocity" $\mathbf{v}$ with an x and z component. Obviously, the z component $vz$ vanishes if we subtract $\rho g$ but the x component $vx$ remains, causing an apparent flow to the right, which clearly is non physical.

If we know $\alpha$ , we can compute vector $\mathbf{x}$ using $\tan\alpha=\mathbf{x}/\mathbf{g}$. Note that $\mathbf{x}$ is equivalent to the apparent $vx$ that we would like to subtract from $\mathbf{v}$ to correct for all hydrostatic effects, both in z and x direction. Any non-hydrostatic pressure effects will not be affected. We can obtain $\alpha$ from the scalar product of $\mathbf{g}$ and $\mathbf{v}$, where the orientation of $\mathbf{v}$ is given by $P1$ - $P1$. The scalar product allows us to compute the angle between two vectors as

(1)\begin{align} \mathbf{v}\cdot\mathbf{g}=|v|\cdot|g|\cos\alpha \end{align}

Note that the scalar product only considers the length and orientation of the vectors intrinsically and can easily be solved for $\cos\alpha$ and we can compute $\alpha$ from the secant, i.e the inverse of $\cos\alpha$. Once we know $\alpha$ , we obtain $\mathbf{x}$ from $\tan\alpha=\mathbf{x}/\mathbf{g}$. Subtracting this value and $\mathbf{g}$ from the real velocity vector then corrects for gravity, not only in the vertical direction but also in the horizontal one. Some simple calculations on a piece and paper show that this corrects properly for gravity but leaves any other pressure gradients in order.

The same technique can be applied in 3D but we need another correction for the apparent offset in the y-direction.

Does this make sense?

Forum category: CSMP++ / CSMP++ bugs (detected and/or fixed)

Forum thread: Bug in 1D line elements ]]>

I already saw this bug in csmp and I have fixed it in the new csmp. The gravity projection is not correct and if you calculate the divergence of velocity field, it gives you a non-zero value. There is a bug also in the 3D case when you use surface fractures. I haven't fixed that part yet. I thing you should slowly move to the new code, because we are in the process of unit testing all classes and we found some bugs in other classes. This is the part of code that calculates the total velocity. You can change it to the old csmp code and use it.

void ReservoirSimulator2D::Compute_vt_AtBaryCenterIncludingGravity() { const uint32 VERTICAL_AXIS(1U); const double64 acc_gravity(9.80665); vector<double64> un(2U); const Point<2U> gvec( 0., -1. ); ScalarVariable flux; VectorVariable<2U> velo; Region<2U,Element>& gref(reservoir_model_.Region("Model")); for ( vector<Element<2U>*>::iterator it=gref.ElementsBegin(); it!=gref.ElementsEnd(); it++ ) { // computing the critical relperm parameters relperm_model_->Initialize( *(*it) ); relperm_model_->InitializeForBaryCenter( *(*it) ); relperm_model_->EffectiveSaturation(); // computing the total velocity: vt = -k (lt grad p - (lw rho_w + lo rho_o) g) const double64 mob_t = relperm_model_->TotalMobility(); velo = 0.; FiniteElementTraits<2U,Element>(*(*it)).dN_AtBaryCenter( DERIV_, 1U ); for ( size_t i=0U; i<(*it)->Nodes(); i++ ) { double64 pf = (*it)->N(i)->Read( props_.pf1_key ); pf += (*it)->N(i)->Read( props_.hp_key ); velo(0) += pf * -DERIV_(0,i) * mob_t; velo(1) += pf * -DERIV_(1,i) * mob_t; } // taking into account the gravitational flow component for calculation of velocity of non-wetting phase // k * (lambda_w * rho_w + lambda_o * rho_o) g const double64 gravity_term = (*it)->Read( props_.gt_key ) * -acc_gravity; // SURFACE ELEMENTS if ( (*it)->FE()->IsSurfaceElement() ) velo(VERTICAL_AXIS) += gravity_term; // special case of lower dimensional elements embedded in 2D else { // LINE ELEMENT // ascertaining that the velocity vector remains aligned with the line element if ( (*it)->FE()->IsLineElement() ) { assert( (*it)->FE()->Interpolation() == 1U ); // linear interpolation=two nodes // 1. find unit vector in direction of line element Point<2U> evec((*it)->N(1U)->Coordinate() - (*it)->N(0U)->Coordinate()); // 2. check direction of evec and correct it to upward if ( evec[1U] < 0. ) evec *= -1.; evec /= evec.Length(); // 3. scaling element aligned unit vector by flow vector gravitational component evec *= evec[1U] * gravity_term; // 4. add resulting velocity components to velocity vector velo(0U) += evec[0U]; velo(1U) += evec[1U]; } } // storing the computed velocity (*it)->Store( props_.vt_key, velo ); // backing up the previous volume flux (*it)->Read( props_.vf1_key, flux ); (*it)->Store( props_.vf0_key, flux ); // volume flux flux = velo.Length(); (*it)->Store( props_.vf1_key, flux ); } extern bool global_verbose; if ( global_verbose ) printRangeOfVariable( reservoir_model_, "velocity" ); } // end Compute_vt_AtBaryCenterIncludingGravity

Cheers,

Shaho

Forum category: CSMP++ / CSMP++ bugs (detected and/or fixed)

Forum thread: Bug in 1D line elements ]]>

Forum category: CSMP++ / CSMP++ bugs (detected and/or fixed)

Forum thread: New functionality and old bugs in CSP_Matrix class ]]>

I stripped down the code to the following stand-along test:

stl_index DIM(2); IsoparametricLinearLineElement elm(DIM,1); Element<csp_float,2> e(&elm); Node<csp_float,2> n0, n1; n0.x(0.0); n0.y(0.0); n1.x(1.0); n1.y(1.0); e.ConnectTo( 0, n0 ); e.ConnectTo( 1, n1 ); csp_float l = e.Volume(); csp_float p[2], v[2]; p[0] = 0.0; p[1] = 1.0; v[0] = v[1] = 0.0; DenseMatrix<csp_float,DM_MIN> DN, XY; e.CoordinateMatrix(XY); XY.Out(); for ( stl_index i=0; i<e.IntegrationPoints(); i++ ) { e.dN_AtIntegrationPoint( DN, i, 1 ); for ( stl_index n=0; n<e.Nodes(); n++ ) for ( stl_index j=0; j<DIM; j++ ) v[j] += p[n] * DN(j,n); } cout << "\n\nFE Gradient X: " << v[0] << ", should be " << (p[1]-p[0])/(n1.x()-n0.x()); cout << "\n\nFE Gradient Y: " << v[1] << ", should be " << (p[1]-p[0])/(n1.y()-n0.y()); cout.flush();

This is a 1D line element with two points at (0,0) and (1,1). There is a pressure of 0 at node 0 and a pressure of 1 at node 1. The length of the element is correctly calculated as square root of 2 and the pressure gradient in X and Y direction must be 1 (with the length of the vector between point 0 and 1 is square root of 2). Now, this is not what using the interpolation function derivatives yield. They yield gradients of 0.5 in X and Y directions. If I use coordinates of the nodes and the pressures from the actual mesh, I can recomputed the gradients that the “real” CSMP gives me, which differ from what I would think are the right ones. It only works if the line element is oriented horizontally or vertically.

Now, aside from the gravity effects, this could be very worrying because it implies that all fluid velocities in 2D DFM models where the fractures are 1D line elements are potentially not correct.

Am I doing something entirely stupid or is there an issue with the 1D line elements in 2D space?

Cheers, Sebastian

Forum category: CSMP++ / CSMP++ bugs (detected and/or fixed)

Forum thread: Bug in 1D line elements ]]>

Computer code: more credit needed

Computer code: incentives needed

Computer code: a model journal

Forum category: Miscellaneous / General discussion zone

Forum thread: Thoughts on publishing scientific code ]]>

Forum category: Miscellaneous / General discussion zone

Forum thread: Any cheap route to find the elemet located at some xyz coordinate? ]]>

Forum category: Miscellaneous / General discussion zone

Forum thread: Thoughts on publishing scientific code ]]>

The idea would be to create a hybrid mesh 3D/2D of the phase diagram of H2O-NaCl. Phase boundaries would be represented by surfaces of, e.g., of triangles, the regions inbetween by volume elements like tetrahedra. I guess it'll be in the order of 10^5-10^6 elements to have sufficient resolution.

I'd need to pseudo-randomly access ANY xyz coordinate (BUT: for a given node in the simulation domain (not the lookup mesh) I'd probably have a good guess from the last time step in what region I should be).

As always, there is a trade-off to be considered: Currently, my 3D-lookup is a cartesian grid with variable resolution in certain regions. From given xyz (which are temperature-pressure-composition) I can jump to the correct position with one very quick operation and linearly interpolate in that rectangual cell.

This works fine, fast and cheap unless I am in a situation where a phase boundary (e.g. liquid/vapor) lies within that cell. Then there is a plethora of possible topologies how exactly that boundary lies in the cell (and whether there are one, two, or three boundaries). Figuring them out is possible but I'd like to avoid going through that pain. Up to now, I extrapolated across the boundary but this is probably not accurate enough for our upcoming strict transport CVFEM scheme (flow gets potentially unstable if fluid properties are even slightly inconsistent with each other).

So, creating an FE-based lookup table looked attractive as it (a) would give a very good geometric representation and (b) has intrisically consistent interpolation routines. The unattractive side would be the cost of finding the right element for interpolation.

One possibility I thought of is creating the mesh such that it'd essentially consist of a series of long prisms which have there long axis strictly parallel to one of the axes (in my case y) and are themselves then subdivided into smaller prism or tretrahedral elements. This would allow to quickly find the right "long" prism first and then loop within it to find the right spot along the y-axis. However, this is not well thought through yet.

Forum category: Miscellaneous / General discussion zone

Forum thread: Any cheap route to find the elemet located at some xyz coordinate? ]]>

Forum category: Miscellaneous / General discussion zone

Forum thread: Any cheap route to find the elemet located at some xyz coordinate? ]]>

Forum category: Miscellaneous / General discussion zone

Forum thread: Any cheap route to find the elemet located at some xyz coordinate? ]]>

As for the second point: Excellent catch! I've updated the config.prj file and, low and behold, the code runs much faster now in release mode… Thanks for being so persistent and finding this!

Forum category: CSMP++ / Running and compiling CSMP++

Forum thread: Compiling CSMP with Qt ]]>

I also noticed that, also for release projects, the **debug** library versions are used:

CONFIG(debug, debug|release) { DESTDIR = ../../../libraries/debug LIBDIR = $${LIBHOME}/debug } else { DESTDIR = ../../../libraries/release LIBDIR = $${LIBHOME}/debug }

Is this on purpose? If so - what are the release versions used for?

Forum category: CSMP++ / Running and compiling CSMP++

Forum thread: Compiling CSMP with Qt ]]>

You don't want to use Store() and Read() because the number of indipendent chemical components that CSMP receives from GEMS will vary from application to application and you want to have the flexibility to add these components to the CSMP property database at runtime and not via a variables text file as required by the Store() and Read() function?

In the pseudo code, doesn't `my_xDC[i]` contain the correct string, which refers to the indipendent chemical component i, after `my_xDC.push_back(dummy)`? This assumes, of course, that `dummy = xDC_scalarvar[i]` works.

Just guessing and not having tried it myself, do you need the detour of the dummy `PropertyHandle`? I think using pointers could work here and do what you are trying to achieve:

std::vector<PropertyHandle<fT,dim>* > my_xDC(niC); // on the fly access to save nIC variables from GEMS to CSMP // initialise pointer of each vector entry for(int i=0; i<nIC; i++) my_xDC[i] = new PropertyHandle<fT,dim>(sg, xDC_scalarvar[i], SCALAR, NODE); // xDC_scalarvar[i] contains name of chemical component

Forum category: CSMP++ / Questions and tricks related to the source code

Forum thread: Painless updating of nodal variable values ]]>

- Yes, whatever works best for your particular Windows system with respect of storing the various dll libraries is fine. I have PATH set to the Qt directory and copied samg_dyn_noomp.dll to the system directory.
- Good catch. I added both to config.prj and it is in the SVN now but you may want to check if you need more than one links to libeos.a

Sebastian

Forum category: CSMP++ / Running and compiling CSMP++

Forum thread: Compiling CSMP with Qt ]]>

- It is ok to copy the file
`samg_dyn_noomp.dll`into the system folder (BTW: for Vista 64bit this would be`SysWOW64`) - though it is not sufficient to do the same with`mingwm10.dll`, because there are more`.dll`s needed which are in the same folder (in my case`C:\Qt\2010.04\qt\bin`). Therefore, adding the PATH variable to this directory is necessary. - For my application, I noticed that in the file
`config.prj`some paths and libraries are missing; namely the path to`csmp\source_code\triangular_finite_volumes`(-> e.g., FiniteVolumeManager) and the library`csmp\libraries\libeos.a`. This might not be the case for other users, though… still it would complete the lists.

Thanks again, Sebastian, for your great support!

Forum category: CSMP++ / Running and compiling CSMP++

Forum thread: Compiling CSMP with Qt ]]>

So, the situation:

The chemical system we want to treat is defined in GEMS before the simulation and we then have nIC independent chemical components. Their concentrations are double, they actually come with a C-Style string as identifier, say in an array component_names[] with nIC entries, so this should - in principle - putting them into the CSMP database possible. Of course, one wants to be flexible with respect to the number nIC and, hence, needs some flexible instantiation scheme for the variables living in the CSMP part of the coupled code.

The concrete problem:

In the to-be-written GEMSVisitor, I'd like to generate the CSMP-equivalent of GEMS' variables, ideally in a loop (here PropertyHandle to be unserstood as pseudo-code):

for(int i = 0; i<nIC; i++){

PropertyHandle components_csmp( supergroup, component_names[nIC], SCALAR, NODE );

}

As far as I can see, PropertyHandle doesn't have an interface to do it directly like this. Does anybody see a more or less elegant way to achieve this?

I had a very crude first incomplete attempt, just as food for thought I post this embarrassingly stupid piece of code here:

…

xDC_scalarvar.resize(nIC); // the concentrations of the components, as a vector of ScalarVariables

std::vector<PropertyHandle<fT,2> > my_xDC;

PropertyHandle<fT,2> dummy( sg, "dummy", SCALAR, NODE );

// replace "dummy" with respective string

for(int i=0; i<nIC; i++){

dummy = xDC_scalarvar[i]; // allowed but don't know what really happens

my_xDC.push_back(dummy); // ditto

// but now: how to replace "dummy" in my_xDC[i] with the correct string?

}

…

Forum category: CSMP++ / Questions and tricks related to the source code

Forum thread: Painless updating of nodal variable values ]]>

Forum category: CSMP++ / Running and compiling CSMP++

Forum thread: Compiling CSMP with Qt ]]>

ad 2. and 3.: So, the CSMP library should be cleaned up at some point…

ad 6.: I tried to add a second path to the directory of

Thanks, Sebastian, for your quick reply - and your useful how-to!

G

Forum category: CSMP++ / Running and compiling CSMP++

Forum thread: Compiling CSMP with Qt ]]>

Forum category: CSMP++ / Questions and tricks related to the source code

Forum thread: Painless updating of nodal variable values ]]>

- There is now particular order in which you need to compile the CSMP libraries. They must be compiled before your compile any executable, of course.
- Only Qt project files are provided for those libraries that are needed to build CSMP.
`computer_science`and`generic_element_centered_finite_volumes`are not integral (the former is not needed at all, I have never tried the latter either in all these years). - I have not compiled distributed_examples using Qt Creator, although this should be done at some point.
- Yes, only
`f2c`,`jpeg`, and`meschach`need to be compiled. If you want to run things in parallel you need`MPI`and`Metis`too, which provide their own make files. - I've seen these errors too but things compile and run fine anyway. I have not worked out the reason behind.
- Ah, ok,
`samg_dyn_noomp.dll`of course should be in your Windows system directory (eg system32 under 32-bit) where Windows looks per default for dll at runtime or you can amend the`PATH`variable and add, like for`mingwm10.dll`, the path to the directory where s`amg_dyn_noomp.dll`is located.

HTH, Sebastian

Forum category: CSMP++ / Running and compiling CSMP++

Forum thread: Compiling CSMP with Qt ]]>

I just started using Qt Creator IDE and followed Sebastian's step-by-step explanation of how to compile CSMP with Qt (see section CSMP-basics). The guide seemed to me quite clear… still, there are a few ambiguities, which I hope you can help me resolve:

- Is there a certain order in which I have to compile the libraries (e.g., do I have to compile the main library or the support libraries before the others)?
- When opening the Qt project files, I noticed that for some folders, there is none (such as
`computer_science`or`generic_element_centered_finite_volumes`). Are they not needed in the CSMP library? - Also for
`distributed_examples`, there are no .pro files. I assume these examples are still not working and haven't been used by anyone lately!? - From the support libraries, only
`f2c`,`jpeg`and`meschach`have to be compiled - right!? 'Cause again, for the others there are no .pro files. - For many libraries, an error message saying "instantiated from here" is occurring - referring to a template class definition (e.g.,
`template class LinearDiffusionAlgorithm<csp_float,2>;`). But the libraries are being compiled anyhow. Can I just ignore those messages? - It says that I have to add the PATH to the file
`mingwm10.dll`to my system environment variables. But if I want to start an .exe by -for example- double-click, also the file`samg_dyn_noomp.dll`is required. Do I always have to copy it into the same folder as the .exe (as I used to do with CodeWarrior)? Or is there another work-around?

No major issues and probably very basic questions - but I thought that other users might come upon them as well… If so, the answers could be incorporated into Sebastian's how-to.

Cheers,

Gillian

Forum category: CSMP++ / Running and compiling CSMP++

Forum thread: Compiling CSMP with Qt ]]>

Forum category: CSMP++ / Questions and tricks related to the source code

Forum thread: Painless updating of nodal variable values ]]>

Forum category: CSMP++ / Questions and tricks related to the source code

Forum thread: Painless updating of nodal variable values ]]>

Forum category: CSMP++ / Questions and tricks related to the source code

Forum thread: Add/remove regions ]]>

So, in CSMP, does anybody see a way to directly use the above to update nodal variables (I may have overlooked a simple approach)?

Or does one have to go the indirect way used in many Visitors, i.e., have all the above function arguments (doubles etc.) as private variables in the visitor and then write back the values via node's Store etc. to the actual variables in the database? This is always a duplication, sometimes triplication of containers for one value just for the purpose of exchanging.

Forum category: CSMP++ / Questions and tricks related to the source code

Forum thread: Painless updating of nodal variable values ]]>

TNode->GEM_to_MT( m_NodeHandle[in], m_NodeStatusCH[in], m_IterDone[in],

m_Vs[in], m_Ms[in], m_Gs[in], m_Hs[in], m_IC[in], m_pH[in], m_pe[in],

m_Eh[in], m_rMB[in], m_uIC[in], m_xDC[in], m_gam[in], m_xPH[in],

m_vPS[in], m_mPS[in], m_bPS[in], m_xPA[in] );

This example is for a simple transport code where the nodes are stored in an array and access to physical variables (such as m_pH) at the node is directly via the index [in] of that node. All these variables m_… reside in the mass transport part of the coupled code and function arguments of GEM_to_MT are references to these.

Forum category: CSMP++ / Questions and tricks related to the source code

Forum thread: Painless updating of nodal variable values ]]>

Forum category: CSMP++ / CSMP++ bugs (detected and/or fixed)

Forum thread: Bug in TwoPhaseImplicitNodeCenteredFVTransport.cpp ]]>

Forum category: CSMP++ / C++ questions

Forum thread: C++ compiler for 64-bit PC ]]>

I tried to compile and execute the tutorial2 project under WinXP64 OS.

The SAMG Solver gets into an infinite loop with the FV-Algorithm or chrashes with the Code Generation/Optimization Level 1 or above. It works fine in case the Optimization is switched off.

It seems as if it depends on the OS, because this error doesn't appear with WinXP(32).

Maybe some additional windows settings are necessary, does somebody have any idea?

Cheers,

Christine

Forum category: CSMP++ / CSMP++ bugs (detected and/or fixed)

Forum thread: CSMP General Setting/Global Optimizations WinXP64 ]]>

Thanks, Sebastian, for your considerations. Here some replies to your questions:

What do you do with your model region that is excluded from the calculations […]?

In the cases I showed I do not have any region that is excluded from the computations, i.e., the whole mesh (including the magma chamber) is part of the group "model", for both cases. I did this to directly compare the results which - in this case - SHOULD actually show exactly the same…

Could there be boundary effects […] that impact the evolution of the flow field?

For both cases, I formed the same groups (e.g., "magma" and "model") and assigned the same initial/boundary conditions. No boundary conditions are assigned to internal group boundaries. The only difference is the restriction of certain applications to the group "model" in one of the cases. I therefore don't think there should be any boundary effects for one case compared to the other.

How does your velocity field look like immediately next to the boundary of "magma chamber" […]?

See pictures below.

[…]what do you do with the permeability?

The permeability is initially set to 1e-14 for the host rock (i.e., region excluding the magma chamber) and 1e-22 for the magma chamber. Throughout the simulation, a temperature dependent permeability is computed for elements within the magma chamber that reach temperatures below the granite solidus (similar to Hayba and Ingebritsen, 1997). In case a permeability change had to be performed, the heat capacity of the element is adjusted to solid rock. Permeability of the host rock remains constant.

t = 10 years:

t = 100 years:

(thin lines are pressure; thick white line is permeability < 1e-14; arrows are liquid velocities)

Forum category: CSMP++ / Questions and tricks related to the source code

Forum thread: Add/remove regions ]]>

interesting observation here. I have worked with the RestrictApplicationTo() function before but never carefully compared this. What do you do with your model region that is excluded from the calculations in those runs where you apply RestrictApplicationTo("model") in the case where you do the calculations for the entire model? In other words, in one simulation you carry out calculations in what looks like a "magma chamber" and in other simulations you exclude the "magma chamber". Could there be boundary effects (e.g., temperatures at the boundary of "magma chamber" remaining constant in one case but not the other) that impact the evolution of the flow field? How does your velocity field look like immediately next to the boundary of "magma chamber" and what do you do with the permeability. I found, in general, that results are very sensitive to the way you treat P, T, and X (and fluid properties) at the boundary of a "magma chamber" and that one needs to take care to have all these values at the same time level (e.g., temperature in the "magma chamber" may cool due to conduction but not advection etc.).

To test the RestrictApplicationTo() function you could design a simple test case where you have an impermeable layer in the centre of your model which you include/exclude in your simulations. If you include it, you make the permeability of the central group very low (1e-25 m2) which gives you a natural no flow boundary. If you exclude the central region, the now flow boundary should be emerge too.

HTH, Sebastian

Forum category: CSMP++ / Questions and tricks related to the source code

Forum thread: Add/remove regions ]]>

Although quite some time has passed, I am writing again with a problem I encountered when working with the suggested group restrictions (but first of all THANKS for your immediate replies - I find this forum really helpful!):

As explained earlier, for my latest runs, I set up a 2D triangle mesh of which I want to use only a certain part for my computations. I.e., I formed different groups and I had to restrict my visitors/interrelations/algorithms to the group I want to run my computations on (I called this group "model").

At first, everything seemed to work and the results looked reasonable - until I noticed that the results produced WITH group restriction look significantly different from the ones computed WITHOUT group restriction: fluid transport takes at least only 1/10 of the time, i.e., is much faster WITH group restriction (see images below)!

As I applied the group restriction to all my visitors (fluid properties visitor (own!), transport properties visitor (own!), velocity and volume flux visitor (csp)), algorithms (transient temperature and pressure), and interrelations (concatenate velocity (csp), modify positive property to max (own!)), I cannot imagine where this effect is coming from. All other parameters/settings are exactly the same for both the simulations…

I'd be glad if you or anyone else who has been working with group restrictions could make a remark on that… 'cause here at ETH nobody else has used this application before.

Cheers,

Gillian

PS: Here some essential lines from my code:

` `` H2OPropertiesVisitorPH_TOPBC<csp_float, 2>* equilibrator_properties_purewater = new H2OPropertiesVisitorPH_TOPBC<csp_float, 2> ( ... ); equilibrator_properties_purewater->RestrictApplicationTo( "model" ); Algorithm<csp_float, 2> transient_temperature( new SAMG_Solver() ); transient_temperature.RestrictApplicationTo( "model" ); MassBasedFiniteVolumeAdvection<csp_float, 2> advection_liquid( fv_manager ); //cannot be restricted to groups (!?) TransportPropertiesVisitorPH<csp_float, 2> flowprop( ... ); flowprop.RestrictApplicationTo( "model" ); VelocityAndVolumeFluxVisitor<csp_float,2> v_liquid( ... ); v_liquid.RestrictApplicationTo( "model" ); Concatenate<csp_float,2,plus> total_v( ... ); total_v.RestrictApplicationTo( "model" ); ModifyPositivePropertyToMax<csp_float,2> T_max_cutting( ... ); T_max_cutting.RestrictApplicationTo( "model" );`

…and three screenshots showing temperature distribution for t = 0, 10 and 100 years, respectively:

(Upper images are WITHOUT group restrictions, lower images are WITH group restrictions.)

Forum category: CSMP++ / Questions and tricks related to the source code

Forum thread: Add/remove regions ]]>

I am pretty sure that this is a fundamental issue of the FE method, not a "feature" of CSMP. If you look at the Istock book, you will see how the global matrix is accumulated for each FE and A should vary (to a certain degree) depending on how many elements are connected to one node. Now, there may be a trick how A can be re-ordered to increase the accuracy, I will ask some mathematicians about this.

How does your solution behave (i.e., compare between quadrilaterals and triangulars) if you use consequtively finer meshes but with the same number of nodes? I suspect the two solutions should converge (and that the large temperature difference that you observe decreases).

Cheers, Sebastian

Forum category: CSMP++ / Questions and tricks related to the source code

Forum thread: Heat Conduction Test ]]>

yes, that's right. The advantage of the little geometry I used was that one can use a quadrilateral mesh with exactly the same nodes. This quadrilateral mesh gives a perfectly uniform front with all nodes at the same x position having exactly the same temperature value throughout the transient simulation.

Comparing the matrices "A" shows that the off-diagonal entries are identical for quadrilaterals (with integration points at the nodes) and triangles, but the values in the diagonal differ. The difference purely depends on the orientation of the triangles, i.e. in which direction you divide the respective quadrilateral into two triangles — which leads to different volumes associated with every node.

So yes, the actual question is exactly that.

Cheers, Philipp

Forum category: CSMP++ / Questions and tricks related to the source code

Forum thread: Heat Conduction Test ]]>

To add on your last sentences: wasn't it even so that when using quadrilaterals for the same geometry, i.e., the same number of nodes at the same positions, you'll get entries in the matrix that are different from the triangle case and, hence, MUST lead to a different solution?

And wasn't the actual question if this "has to be so" or if this is specific to how the FE is implemented in CSMP?

Or did I miss something in our discussion?

Cheers, Thomas

Forum category: CSMP++ / Questions and tricks related to the source code

Forum thread: Heat Conduction Test ]]>

thanks a lot for your reply.

The test works fine in 1D (or rather pseudo-2D with a line of quadrilaterals). And I tried to solve a 1D problem in 2D with only a few triangles on purpose to test whether this comparatively simple process can be accurately captured. I think it might be a basic inaccuracy that builds up to cause bigger problems when we want to calculate more complex physics.

So did I get it right that essentially it's a known inaccuracy of the finite element method?

It's fine for me that the numerical solution differs from the analytical solution depending on the temporal and spatial resolution and I can imagine that this error will decrease with higher resolution.

I'm still worried about the inconsistency within the numerical solution itself, though. What I mean is that even though it's a 1D problem I get different values for nodes at the same position x depending on the grid orientation, i.e. directly depending on the number of parent elements (when using constant element sizes and hence uniform resolution). I also used finer meshes for my tests as well and they revealed the same pattern, this simple one was just the easiest way to document the problem. I still have the feeling that is something more than just an approximation error.

Cheers, Philipp

Forum category: CSMP++ / Questions and tricks related to the source code

Forum thread: Heat Conduction Test ]]>

There is a bug in the ANSYS bit that generates an output file for CSMP. It is probably triggered when you use a 3D mesh that has no boundary flags, i.e. no TOP, LEFT, etc (at least that is how I triggered it). If you read in such a mesh, you might end up having the following CSMP error:

` ``MeshManager::ParseBoundary Error: Boundary flag from vset could not be identified. Flag: -30`

The workaround that I've found is opening the mesh .dat file in a hex-editor and replacing all the -30 values in it (E2 FF FF FF in hexadecimal representation) with zeros.

Yan

Forum category: Pre-processing / Other

Forum thread: Fiddling with an ANSYS mesh ]]>

this is an interesting problem, and one that I observed at another occasion when using triangular FEs — when you simulate density driven flow and you have, say, a high density (high-salinity) fluid at the top boundary and a low-density (low-salinity) fluid everywhere else, you observe different element velocities in the FEs at the top boundary, depending if they share one or two FEs with the top boundary, which impacts how density is averaged across the FE. And I don't think you are doing something wrong with the PDE operators (or they are wrong per se for this instance).

Now, your mesh is obviously very coarse and the error should decrease as you refine the mesh. Your problem is essentially 1D and you could use the 1D analytical solution for the diffusion equation to compare your numerical and analytical results at each x-y coordinate, calculate the different between the anayltical and numerical result (in $L^2$ space, I can show you how) and plot it as a function of, say, the average FE size $h$. If plotted in log-log space, you should see how the error decreases, I cannot remember of the top of my head if it is with $\mathcal{O}(h)$ or $\mathcal{O}(h^2)$, i.e. with linearly with $h$ or quadratically with $h$. If you use quadratic FEs, you should see how your error decreases faster (i.e., quadratically or cubically). In the end, it is probably something one needs to live with as any numerical scheme is just an approximation to the PDE and only a small enough $h$ and $\Delta t$ will approximate the equation accurately. But I will check with people at mathematics if there are tricks that can be used in such a case.

Cheers, Sebastian

Forum category: CSMP++ / Questions and tricks related to the source code

Forum thread: Heat Conduction Test ]]>

I have a question/problem concerning a very simple heat conduction test I performed with finite elements. I want to solve the basic heat conduction equation on a regular 1500m x 1000m grid consisting of 12 nodes and elements only. Unfortunately I added a few images to describe the problem but didn't know how to include it into this thread. So I would really appreciate if you could have a quick (or long) look at this document:

Thanks, Philipp

Forum category: CSMP++ / Questions and tricks related to the source code

Forum thread: Heat Conduction Test ]]>

assert( iFacet < e.ConnectedFiniteVolumeStencil()->Sectors());

which should obviously be

assert( iFacet < e.ConnectedFiniteVolumeStencil()->Facets());

Forum category: CSMP++ / CSMP++ bugs (detected and/or fixed)

Forum thread: Bug in ElementFiniteVolumeTraits in 3D ]]>

That's right, PointSource_rhsop just puts the nodal value in the RHS vector for every node. In my case I used it to assign the Neumann boundary condition, which is formulated as a surface integral. In order to do this properly, for every boundary node I stored the "nodal value x nodal surface" and fed this to the PointSource.

Yan

Forum category: CSMP++ / CSMP++ bugs (detected and/or fixed)

Forum thread: Wrong treatment of source terms in FV classes ]]>

Sort of unrelated to what you posted here but interestingly enough we discovered inconsistencies in our formulation of the source term in the FE pressure equation recently. We realized that the PDE operator PointSource_rhsop does not consider the volume of the respective element, meaning that the variable introduced via PointSource_rhsop should be calculated as q x V instead of just q.

Not sure whether that's of interest for anyone but us.

Thanks for your excellent post, though.

Philipp

Forum category: CSMP++ / CSMP++ bugs (detected and/or fixed)

Forum thread: Wrong treatment of source terms in FV classes ]]>

` ``elmt_status_list[ pmesh->E( (*iter_e).first-1 ).ID() ] = flag;`

instead of

` ``elmt_status_list.insert( make_pair( (*iter_e).first, flag ) );`

(This is being done in

Forum category: CSMP++ / Questions and tricks related to the source code

Forum thread: FormAndAddGroup // InterfaceVisitor ]]>

Forum category: CSMP++ / Questions and tricks related to the source code

Forum thread: FormAndAddGroup // InterfaceVisitor ]]>

I was calling different functions of the InterfaceVisitor at different stages in my simulation (e.g., *InterfaceArea()* before initial computations and *InFluxMinusOutFlux()* for every output timestep). I wasn't aware that one has to "Accept" the InterfaceVisitor everytime again when using one of its functions. I.e., to calculate the flux (e.g., "pore velocity") across a certain boundary, the Interface Visitor has to be accepted by the SuperGroup AFTER the pore velocity has been calculated - and not whenever the InterfaceVisitor was constructed or the InterfaceArea was queried.

So, no problem with the code - just a matter of correct application ;-)

Forum category: CSMP++ / Questions and tricks related to the source code

Forum thread: FormAndAddGroup // InterfaceVisitor ]]>

Group boundary flagging for elements, nodes and constraint points is done within the function

` ``void Group<fT,dim>::IdentifyBoundaryAs( DATA_STYLE flag )`

The flagging itself for ELEMENTS is done via

` ``elmt_status_list.insert( make_pair( (*iter_e).first, flag ) );`

while for their NODES and CONSTRAINT POINTS it is done via

` ``node_status_list[ pmesh->E( (*iter_e).first-1 ).ConnectedNode(j)->ID() ] = flag; cpnt_status_list[ pmesh->E( (*iter_e).first-1 ).ConnectedConstraintPoint(j)->ID() ] = flag;`

Can you tell me why there is such a difference? 'Cause it seems that the flagging of NODES does work well, while the flagging of ELEMENTS does not! (I assume it would actually work for CONSTRAINT POINTS as well - though there are none in my model.)

Couldn't the flagging be done for ELEMENTS as well via:

` ``elmt_status_list[ pmesh->E( (*iter_e).first-1 ).ID() ] = flag;`

(…and if not - why not?)

Forum category: CSMP++ / Questions and tricks related to the source code

Forum thread: FormAndAddGroup // InterfaceVisitor ]]>

Thanks, Sebastian, for your answer!

Forum category: CSMP++ / Questions and tricks related to the source code

Forum thread: FormAndAddGroup // InterfaceVisitor ]]>

Forum category: CSMP++ / Questions and tricks related to the source code

Forum thread: FormAndAddGroup // InterfaceVisitor ]]>